Horizontal Pod Autoscaling
Create an HPA named prep-hpa for the Deployment prep-server in namespace auto-scale. Requirements: CPU target: 50% utilization per pod Min replicas: 1 Max replicas: 4 Downscale stabilization window:…
Live lab access
This task description is public. Its live lab requires full access; six other CKA labs are available in Free Practice with AI Lab Coach.
Create an account to continue →
Explore the six free labs with AI Lab Coach →
Read the brief on any device. Use a desktop or laptop for the terminal lab. Nothing starts until you choose Start.
The task
Create an HPA named prep-hpa for the Deployment prep-server in namespace auto-scale.
Requirements:
- CPU target: 50% utilization per pod
- Min replicas: 1
- Max replicas: 4
- Downscale stabilization window: 30 seconds
Original Prepium workshop · Tested on Kubernetes v1.35.0 on 1 October 2026 in a three-node kind cluster with metrics-server. Use a disposable cluster. The HorizontalPodAutoscaler reads CPU from the Metrics API, so kubectl top pods must work before anything below can scale.
Autoscale a Deployment on CPU, then control how fast it scales back down
An HPA compares the average CPU usage of a workload's Pods with a target expressed as a percentage of each container's CPU request. If the Pods use more than the target, it adds replicas; if they use less, it removes them, within the min and max you set. Two things therefore have to exist before an HPA can do anything: a running metrics pipeline and a CPU request on every container it measures.
load ──→ cpu-demo Pods (request 100m) ──→ metrics-server ──→ HPA (target 60%) ──→ Deployment replicas 1..5
1. Deploy a workload with a CPU request
Save this as hpa-workload.yaml. The image is the CPU-burning PHP demo used in the upstream Kubernetes walkthrough. The 100m request is the denominator for every utilization figure the HPA reports.
apiVersion: apps/v1
kind: Deployment
metadata:
name: cpu-demo
namespace: prepium-tutorial
spec:
replicas: 1
selector:
matchLabels:
app: cpu-demo
template:
metadata:
labels:
app: cpu-demo
spec:
containers:
- name: web
image: registry.k8s.io/hpa-example
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
limits:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: cpu-demo
namespace: prepium-tutorial
spec:
selector:
app: cpu-demo
ports:
- port: 80
kubectl create namespace prepium-tutorial
kubectl apply -f hpa-workload.yaml
kubectl -n prepium-tutorial rollout status deployment/cpu-demo
kubectl -n prepium-tutorial top pods
If kubectl top answers Metrics API not available, install or repair metrics-server first. An HPA created now would show <unknown> targets forever.
2. Write the HPA with autoscaling/v2
kubectl autoscale creates a working HPA quickly (--cpu=60% --min=1 --max=5), but it has no flag for the behavior section. Scaling policies and stabilization windows only exist in the autoscaling/v2 object, so write it as YAML or edit the generated object. Save this as hpa-v2.yaml.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: cpu-demo
namespace: prepium-tutorial
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: cpu-demo
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleDown:
stabilizationWindowSeconds: 120
kubectl apply -f hpa-v2.yaml
kubectl -n prepium-tutorial get hpa cpu-demo
kubectl -n prepium-tutorial get hpa cpu-demo -o jsonpath='{.spec.behavior.scaleDown}'
Within a minute the TARGETS column should show a real reading such as cpu: 1%/60%. The second command proves the scale-down window was stored; if you used autoscaling/v1 the field would not exist.
3. Generate load and watch it scale
kubectl -n prepium-tutorial run load --image=busybox:1.36 --restart=Never -- \
/bin/sh -c "while true; do wget -q -O- http://cpu-demo >/dev/null; done"
kubectl -n prepium-tutorial get hpa cpu-demo --watch
In our run the reading climbed to cpu: 192%/60% and the HPA jumped straight from 1 to 4 replicas in one step, recording New size: 4; reason: cpu resource utilization (percentage of request) above target in kubectl describe hpa. The controller computes the replica count as current replicas × current utilization ÷ target, rounded up, so a large overshoot produces a large step.
Now delete the load generator with kubectl -n prepium-tutorial delete pod load and keep watching. Usage drops at once, but the replica count holds until the 120-second stabilizationWindowSeconds has passed. The window makes the HPA act on the highest recommendation it computed during that period, which stops it from flapping when traffic is bursty. Without a behavior section the default scale-down window is 300 seconds.
4. See the most common failure
kubectl -n prepium-tutorial create deployment no-requests --image=registry.k8s.io/hpa-example
kubectl -n prepium-tutorial autoscale deployment no-requests --cpu=60% --min=1 --max=3
kubectl -n prepium-tutorial describe hpa no-requests
This one never scales. The conditions show FailedGetResourceMetric with missing request for cpu in container hpa-example. A utilization target is a percentage of the request, and there is no request to take a percentage of. Add a CPU request to the Pod template (for example with kubectl set resources) and the HPA recovers without being recreated.
| Example check | Evidence |
|---|---|
| HPA targets the right workload | scaleTargetRef names the Deployment; REFERENCE column matches |
| Bounds and target are set | MINPODS, MAXPODS and the /60% part of TARGETS |
| Scale-down is damped | spec.behavior.scaleDown.stabilizationWindowSeconds is present |
| Metrics flow | TARGETS shows a number, not <unknown> |
Variation: add behavior.scaleUp.policies with type: Pods, value: 1, periodSeconds: 30 and repeat the load test. Predict the replica count after one minute before you look.
Cleanup: kubectl delete namespace prepium-tutorial. Reference: Horizontal Pod Autoscaling. Next, try resource requests under a quota or CKAD resource management.
What this tests
Run and schedule workloads - deployments, autoscaling, taints and tolerations, affinity, and resource limits. On the CKA exam, Workloads & Scheduling tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.
Practice it for real
The public description lets you study the task before signing up. Full access includes every live lab. Six selected CKA scenarios are included in Free Practice, with five shared sessions each week. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.