Crisp answer: Cluster Autoscaler watches for pods that cannot be scheduled due to insufficient resources and scales up the ASG to add nodes. It also scales down by identifying nodes whose pods can be moved elsewhere.
How scale-up works:
1. New pod created (Deployment scaled, job submitted, HPA triggers)
2. Scheduler tries to place it — no node has enough CPU/memory
3. Pod goes Pending
4. Cluster Autoscaler sees the Pending pod
5. Calculates which node group would satisfy the pod's requirements
6. Increases ASG desired count by 1 (or more if multiple pods pending)
7. New node joins the cluster, becomes Ready
8. Scheduler places the pod on the new node
How scale-down works:
1. CA checks every 10 seconds for underutilised nodes
2. If a node's requests are below 50% for 10 minutes
3. CA checks if all pods on that node can be rescheduled elsewhere
4. If safe: CA cordons and drains the node
5. ASG terminates the instance
Scale-down blockers — pods that prevent scale-down:
- Pods with no controller (standalone pods, not in a Deployment)
- Pods with local storage (emptyDir, hostPath)
- Pods that cannot be evicted (PDB blocks eviction)
- Pods with the annotation: cluster-autoscaler.kubernetes.io/safe-to-evict=false
Installation on EKS:
# Cluster Autoscaler Deployment (simplified)
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
template:
spec:
serviceAccountName: cluster-autoscaler # needs IRSA role
containers:
- name: cluster-autoscaler
image: registry.k8s.io/autoscaling/cluster-autoscaler:v1.29.0
command:
- ./cluster-autoscaler
- --cloud-provider=aws
- --nodes=2:10:my-node-group # min:max:ASG-name
- --balance-similar-node-groups # balance across AZs
- --skip-nodes-with-local-storage=false
- --expander=least-waste # which node group to scale up
Required ASG tags:
aws autoscaling create-or-update-tags --tags \
ResourceId=my-asg,ResourceType=auto-scaling-group,\
Key=k8s.io/cluster-autoscaler/enabled,Value=true,PropagateAtLaunch=false \
ResourceId=my-asg,ResourceType=auto-scaling-group,\
Key=k8s.io/cluster-autoscaler/my-cluster,Value=owned,PropagateAtLaunch=false
Expander strategies:
least-waste: Choose the node group that wastes the fewest resources
(most CPU/memory used relative to the node size)
random: Pick randomly (spreads load, simple)
most-pods: Choose the node group that schedules the most pending pods
priority: Prefer node groups by configurable priority
Karpenter — the modern alternative:
Karpenter is a newer autoscaler (open-sourced by AWS):
- Provisions nodes in 60 seconds vs 3-5 minutes for CA
- Provisions exactly the right instance type for pending pods
- Handles spot interruption and consolidation natively
- Does not use ASGs — calls EC2 APIs directly
- Recommended for new EKS deployments
What to say in the interview:
"Cluster Autoscaler watches for Pending pods and scales the ASG up when pods cannot be scheduled. Scale-down is more conservative: a node must be underutilised for 10 minutes and all its pods must be safely reschedulable. PodDisruptionBudgets block eviction during scale-down so they are critical for ensuring CA doesn't take down your last replica. Karpenter is the modern replacement for CA on EKS: it provisions nodes in 60 seconds versus 3-5 minutes, selects the optimal instance type for each batch of pending pods, and handles spot interruption natively. For a new EKS cluster I would choose Karpenter."