All modules in this track (20)
In this module, you'll learn to:
- Explain why resource requests drive scheduling, autoscaling, and cost
- Combine pod autoscaling (HPA) with node autoscaling (Cluster Autoscaler or Karpenter)
- Protect workloads during scale-down with PodDisruptionBudgets
Before you start: you'll want metrics-server running in the cluster (Platform Add-ons covers installing it) and kubectl top working.
Requests are a promise, and the cluster plans around them
Every scaling decision in Kubernetes starts from resource requests. The scheduler places a pod on a node only if the node has room for what the pod requests, not what it actually uses. Node autoscalers add nodes when pods can't be placed. The Horizontal Pod Autoscaler measures CPU as a percentage of the request.
So when requests are wrong, everything built on top of them is wrong too. Set them too high and you pay for nodes that sit half-empty. Set them too low, or leave them out, and pods get packed onto nodes that can't actually carry them.
Pods, Deployments & Rollouts explains requests and limits in full. The short version: requests reserve capacity, a CPU limit throttles, and a memory limit kills.
Two layers of autoscaling
It helps to keep the two layers apart in your head:
- Pods scale out with the Horizontal Pod Autoscaler (HPA). It adds or removes replicas based on a metric, usually CPU or memory usage relative to the request.
- Nodes scale out with Cluster Autoscaler or Karpenter. They add capacity when pods are stuck in
Pendingbecause no node has room, and remove nodes that sit mostly idle.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # 70% of the CPU *request*, not of the nodeThe HPA needs metrics-server (or another metrics source) running in the cluster, and it needs requests set on the pods it watches. Without a CPU request there's nothing to calculate a percentage against, and it won't scale on CPU.
Here's how the two layers work together when traffic spikes:
Choosing a node autoscaler
- Cluster Autoscaler works through your existing node groups. It grows or shrinks an Auto Scaling group, so every new node looks like the ones you defined up front. It's predictable and easy to reason about.
- Karpenter skips node groups and launches EC2 instances directly, picking instance types that fit the pods that are waiting. It usually packs workloads more tightly and reacts faster, and it can mix Spot and On-Demand capacity. The trade-off is that you describe what's allowed rather than exactly what you get.
- Whichever you choose, run one. Two node autoscalers acting on the same capacity will fight each other.
Keeping scale-down from hurting you
Scaling in is where outages hide. When a node autoscaler removes a node, or a Spot instance is reclaimed (AWS gives a two-minute warning), the pods on it are evicted. A PodDisruptionBudget tells Kubernetes how many replicas must stay up during that kind of voluntary disruption.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api
spec:
minAvailable: 2
selector:
matchLabels:
app: api
A PDB only protects against voluntary disruptions: drains, scale-downs, upgrades. It does nothing for a crash or a node that dies outright. For that you still need more than one replica, spread across Availability Zones.
Implementation notes
- Start from real usage, not guesses. Watch actual CPU and memory for a week (
kubectl top pods, Container Insights, or your metrics stack) and set requests a little above the typical peak. - A PDB with
minAvailableequal to the replica count blocks every drain. It looks safe, but it quietly stops node upgrades and scale-down until someone notices. - Idle capacity is the most common hidden cost. Nodes sized for requests that nobody uses cost exactly the same as busy ones. Check the gap between requested and used resources regularly.
- Spot suits stateless, replicated workloads. Keep anything that can't tolerate a two-minute eviction on On-Demand capacity.
Key terms
- HPA: the Horizontal Pod Autoscaler, which changes replica counts based on a metric.
- Cluster Autoscaler: grows and shrinks node groups when pods can't be placed or nodes sit idle.
- Karpenter: launches right-sized EC2 instances directly for waiting pods.
- PodDisruptionBudget (PDB): how many replicas must stay up during voluntary disruptions.
- Throttling: slowing down a container that goes over its CPU limit.
Pop quiz
Five questions: three on the ideas in this module, and two scenarios where you apply them. The order changes every time you take it, and 4 out of 5 passes.
5 questions. Decide on your answer to each, then check it.
-
Concept
An HPA targets 70% CPU utilization. 70% of what?
Show answer
The pods' CPU request
The HPA measures usage as a percentage of the request. Without a CPU request there's nothing to calculate against, so it won't scale on CPU.
-
Scenario
The HPA adds pods, but some stay
Pending. What adds capacity for them?Show answer
The node autoscaler (Cluster Autoscaler or Karpenter), reacting to the Pending pods
Pod autoscaling and node autoscaling are separate layers. Pending pods are the signal for the node autoscaler to add a node.
-
Scenario
A PDB sets
minAvailableequal to the Deployment's replica count. What's the side effect?Show answer
Node drains, upgrades, and scale-down are blocked, because no pod may ever be evicted
A budget that allows zero disruptions stalls every voluntary eviction. It looks safe, but it quietly stops upgrades and scale-down.
-
Concept
Requests are set far higher than what pods actually use. What's the main effect?
Show answer
You pay for nodes that sit mostly empty
The scheduler reserves what's requested, so nodes fill up on paper while staying idle in reality. That idle capacity is a common hidden cost.
-
Concept
What doesn't a PodDisruptionBudget protect against?
Show answer
A node that crashes outright
PDBs only cover voluntary disruptions. For crashes you still need several replicas, spread across Availability Zones.