-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Hello, it would be nice to be able to autoscale WorkloadDeployments with k8s builtin HPA. I was unaware of whether it is possible, so I tried to do it, but with no success. I am not an expert on k8s autoscaling so mostly debugged my deployments with the help of LLM and search engines. Here is what I learned:
- In order to autoscale custom resources, one must define [https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#scale-subresource](
/scalesubresource). - There was no such subresource defined in WorkloadDeployment CR, so I added it there myself like this:
scale:
specReplicasPath: .spec.replicas
statusReplicasPath: .status.replicas
labelSelectorPath: .status.labelSelector- With this addition I was able to scale workloaddeployment with
kubectl scale workloaddeployment <name> --replicas 3 - Now I tried to deploy an HPA to do autoscaling, after adding the scale subresource, the HPA resource found the workloaddeployment, but describing the HPA resource revealed:
Metrics: ( current / target )
"http_requests_per_second" (target average value): <unknown> / 10
Min replicas: 1
Max replicas: 100
...
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True SucceededGetScale the HPA controller was able to get the target's current scale
ScalingActive False InvalidSelector the HPA target's scale is missing a selector
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning SelectorRequired 4s horizontal-pod-autoscaler selector is required
Warning FailedComputeMetricsReplicas 4s horizontal-pod-autoscaler selector is required
- Next I tried to scale it with KEDA, but it uses HPA under the hood and the HPA resource created by KEDA had exactly same event complaining that selector is required.
- Then I found this https://github.com/kedacore/keda/issues/5898 stating that the
/scaleneeds to be implemented correctly for it to work, so I concluded that autoscaling is not possible right now.
I was running my test on k0s cluster using nginx ingress controller and prometheus to create http_requests_per_second metric, so the used metric was external. I have tested it with regular container deployments, and it was working fine with them. Testing was done on ubuntu 24.04 lts (x86_64) and versions used in the test are:
export CONTAINERD_VERSION_STRING=2.2.0-2~ubuntu.24.04~noble
export K0S_VERSION=v1.32.11+k0s.0
export KEDA_VERSION=2.18.3
export WC_VERSION=v2.0.0-rc.6 # wasmcloudBecause there is no images for wasmcloud rc.6, I cloned the repo and built the images myself.
Finally, here is the manifest I used to deploy the workload and HPA:
apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: WorkloadDeployment
metadata:
name: wash-go-server
spec:
replicas: 1
template:
spec:
hostSelector:
hostgroup: default
components:
- name: go-server
image: 10.164.178.1:5000/wash-go-server:0.1.0
hostInterfaces:
- namespace: wasi
package: http
interfaces:
- incoming-handler
config:
host: nuhakala.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: go-ingress
annotations:
"nginx.org/proxy-pass-headers": "Host"
spec:
ingressClassName: nginx
rules:
- host: nuhakala.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: runtime-gateway
port:
number: 80
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: go-deploy-hpa-workload
namespace: default
spec:
scaleTargetRef:
apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: WorkloadDeployment
name: wash-go-server
minReplicas: 1
maxReplicas: 100
metrics:
- type: External
external:
metric:
name: http_requests_per_second
target:
type: Value
averageValue: 10
behavior:
scaleDown:
stabilizationWindowSeconds: 60