kubectl scale sets a number. A HorizontalPodAutoscaler (HPA) sets it for you, from what the Pods are actually doing.
Create one
kubectl autoscale deployment market-web --min=1 --max=5 --cpu-percent=50
kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
market-web Deployment/market-web cpu: 4%/50% 1 5 1 30sTARGETS reads current over target. The current figure is the average over the Deployment's Pods of usage divided by request. That ratio is why the HPA needs requests: a Pod that requested nothing has no denominator, and TARGETS shows <unknown>.
The arithmetic
Every 15 seconds the controller reads usage from metrics-server, the same source as kubectl top, and computes:
desired = ceil( current replicas × current utilisation / target )The result is clamped between min and max, and small differences, within ten percent of the target, are ignored.
Up fast, down slow
Scale-up happens as soon as the numbers say so. Scale-down waits out a stabilization window (five minutes by default on a real cluster, one minute here) so that a short dip does not remove Pods that are needed again a moment later. During the wait kubectl describe hpa says ScaleDownStabilized.
Reading it
kubectl describe hpa market-webMetrics: ( current / target )
resource cpu on pods (as a percentage of request): 41% (41m) / 50%
Min replicas: 1
Max replicas: 5
Deployment pods: 4 current / 4 desired
Events:
Normal SuccessfulRescale New size: 4; reason: cpu resource utilization (percentage of request) above targetAn HPA and a hand-set replicas: fight each other; the HPA wins at its next sync. Once a Deployment has an HPA, leave spec.replicas alone.