An HPA is a control loop in the controller manager. Every 15 seconds it reads a metric for its target's Pods and computes desiredReplicas = ceil(currentReplicas x currentValue / targetValue). For CPU the value is utilization as a percentage of the request: three Pods at 140% of their request with a 70% target ask for ceil(3 x 140 / 70) = 6. Changes within 10% are ignored, scale-up acts at once, and scale-down waits out a 300-second stabilization window, so a brief lull removes nothing. A Pod without a CPU request cannot be measured this way.
The numbers come from the resource metrics API (metrics.k8s.io), served by metrics-server 6,745 (github.com/kubernetes-sigs/metrics-server (https://github.com/kubernetes-sigs/metrics-server 6,745 ), Apache-2.0, v0.9.0), which scrapes every kubelet each 15 seconds and keeps only the latest values: enough for autoscaling and kubectl 5,150 top, not a monitoring system (Observability and Debugging). kind 14,561 's kubelets have self-signed certificates, so kind, and only kind, needs --kubelet-insecure-tls:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.9.0/\
components.yaml >/dev/null
kubectl -n kube-system patch deployment metrics-server --type=json -p='[{"op": "add",
"path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'
kubectl -n kube-system rollout status deployment/metrics-server >/dev/null
until kubectl top pods -l tier=api >/dev/null 2>&1; do sleep 5; done
kubectl top nodes && kubectl top pods -l app=booknestdeployment.apps/metrics-server patched NAME CPU(cores) CPU(%) MEMORY(bytes) MEMORY(%) l3-booknest-control-plane 238m 5% 654Mi 2% l3-booknest-worker 381m 9% 495Mi 1% NAME CPU(cores) MEMORY(bytes) api-6cbf65d77f-5x9mp 1m 21Mi api-6cbf65d77f-7ndq4 1m 20Mi api-6cbf65d77f-f7c6h 1m 20Mi postgres-0 5m 30Mi web-ccd64df5f-gwkxn 0m 4Mi