How-to
Cluster autoscaling¶
Let a BKS cluster add worker nodes when pods can't be scheduled, and remove them when they're no longer needed, between a minimum and a maximum you set.
The cluster autoscaler watches for pods that can't be scheduled because no worker has room for them, and adds a worker. When a worker has been underused for a while and its pods fit elsewhere, it moves them and removes the worker. It works with the resource requests in your pods, so give every container a CPU and memory request. To change the number of pods with load instead, see Horizontal pod autoscaling; the two work together.
You turn autoscaling on when you create the cluster, with labels. The portal's New cluster form has no autoscaling settings, so use the CLI or OpenTofu.
Before you start¶
- Everything in Create a cluster, including an unrestricted application credential.
- Quota for the maximum number of workers: see Quotas and limits.
Create a cluster with autoscaling¶
| Label | Value |
|---|---|
auto_scaling_enabled |
true |
min_node_count |
The fewest workers to keep |
max_node_count |
The most workers to add |
Merge these labels with the template's, which set the Kubernetes version. Without merging, they replace the template's labels.
resource "openstack_containerinfra_cluster_v1" "web" {
name = "web-cluster"
cluster_template_id = data.openstack_containerinfra_clustertemplate_v1.k8s.id
master_count = 1
node_count = 1
keypair = "<key-name>"
merge_labels = true
labels = {
auto_scaling_enabled = "true"
min_node_count = "1"
max_node_count = "3"
}
}
Start --node-count or node_count within the range. Once the autoscaler manages the workers, leave the count to it rather than resizing by hand.
Check the settings¶
openstack --os-cloud <cloud-name> coe nodegroup show web-cluster default-worker -c labels -c min_node_count -c max_node_count
The labels include auto_scaling_enabled set to true, with your minimum and maximum.
Watch it scale¶
Run more replicas than the workers have room for. This deployment asks for half a vCPU per pod:
scale-test.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: scale-test
spec:
replicas: 1
selector:
matchLabels:
app: scale-test
template:
metadata:
labels:
app: scale-test
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.10
resources:
requests:
cpu: 500m
memory: 256Mi
kubectl apply -f scale-test.yaml
kubectl scale deployment scale-test --replicas=20
kubectl get pods --field-selector=status.phase!=Running
kubectl get nodes
The first command lists the pods that don't fit yet. Within a few minutes a new worker joins, shows Ready, and the pods start on it. If the maximum is reached and pods still don't fit, they wait until the replicas go down or the maximum goes up.
Scale back down, and the autoscaler removes the extra workers once they've been underused for about 10 minutes, down to the minimum:
Check it worked¶
- With more pods than fit,
kubectl get nodesshows more workers, up to the maximum. - After scaling back, the workers drop back towards the minimum.
kubectl delete -f scale-test.yamlremoves the test.
Related¶
- Performance efficiency: capacity that follows demand.
- Sustainability: running only what the load needs.
- Horizontal pod autoscaling: more pods with load.
- Create a cluster: clusters and node counts.