Horizontal Pod Autoscaler (HPA)
Watches a metric against a target and adjusts a Deployment's replica count to match, within bounds.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: docktionary-app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: docktionary-app
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70kubectl apply -f hpa.yaml
kubectl get hpa
kubectl describe hpa docktionary-app # see current vs. target utilizationThe HPA needs requests set on the Deployment's containers — it scales based on utilization relative to the requested amount, not an absolute number.
Vertical Pod Autoscaler (VPA)
Instead of changing replica count, the VPA recommends — or, in auto mode, applies — changed CPU/memory requests for a Pod based on observed usage. It's a separate, optional component, not part of the Kubernetes API server by default, and it generally shouldn't run in auto mode alongside the HPA on the same metric.
Cluster autoscaler
Where the HPA scales Pods, the cluster autoscaler scales the nodes underneath them. It adds a node when Pods are stuck Pending for lack of capacity, and removes nodes that are underused and can be safely drained.
kubectl get pods --field-selector=status.phase=Pending
kubectl describe pod <pending-pod> # events: "Insufficient cpu" etc. is
# exactly what triggers a scale-upThe two work as a chain: load increases → HPA adds Pods → some are unschedulable → cluster autoscaler adds a node → the Pods schedule. Scaling down runs the same chain in reverse, more cautiously, to avoid flapping.
Karpenter: a faster, more flexible alternative
Karpenter (originally AWS, now a CNCF project with broader provider support) replaces the node-group model entirely. Instead of scaling a pre-defined, fixed-shape node group, it looks at the exact unschedulable Pods and provisions nodes sized and typed to fit them directly — no node group to pre-configure for every instance type you might need. It generally provisions faster than the classic cluster autoscaler and binpacks more tightly, at the cost of being a separate thing to install and learn rather than a managed feature you just enable.
Pod Disruption Budgets
A scale-down drains nodes by evicting their Pods. A PodDisruptionBudget stops that eviction from taking down too many replicas of the same app at once, protecting availability during voluntary disruptions like a scale-down or a node upgrade.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: docktionary-app
spec:
minAvailable: 2
selector:
matchLabels:
app: docktionaryKEDA: scaling on more than CPU
For scaling on a queue depth, a request rate, or any external metric rather than CPU/memory, KEDA extends the HPA with dozens of event-source scalers (SQS, Kafka, Prometheus, and more) without needing a custom metrics server of your own.