Lab 20 - Autoscaling with HPA

Lab 20 - Autoscaling with HPA

Goal: put load on an application and watch it scale out - and back in. Chapter: Autoscaling with HPA

Requires metrics-server from Lab 19.

# 1 - a CPU-hungry app WITH a CPU request
cd ~
kubectl create deploy php-apache --image registry.k8s.io/hpa-example
kubectl set resources deploy php-apache --requests=cpu=200m --limits=cpu=500m
kubectl expose deploy php-apache --port 80
kubectl rollout status deploy/php-apache
# 2 - the HPA: target 50 % of the request, 1-6 replicas, fast scale-down for the lab
cat > hpa.yaml <<'YAML'
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 6
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 30
YAML
kubectl apply -f hpa.yaml
kubectl get hpa php-apache            # TARGETS cpu: 0%/50% (may show <unknown> for ~30 s)
# 3 - load (in a second terminal, leave it running)
kubectl run load --image busybox:1.36 --restart=Never -- \
  sh -c 'while true; do wget -q -O- http://php-apache; done'
# 4 - watch it scale out
kubectl get hpa php-apache -w          # Ctrl-C after a few minutes
kubectl get deploy php-apache
kubectl describe hpa php-apache | tail -8

TARGETS jumps to 200-300 %, REPLICAS climbs until the average is back near 50 %. The events show each decision: New size: 4; reason: cpu resource utilization (percentage of request) above target.

# 5 - stop the load, watch it scale in
kubectl delete pod load
kubectl get hpa php-apache -w          # back to 1 after ~1 min

Without our stabilizationWindowSeconds: 30 this would take 5 minutes - by design.

Discovery

Infodiscover

Task A. Create a Deployment nolimits (nginx:1.27) without requests and an HPA for it at 50 % CPU. What does the HPA show, and why?

kubectl create deploy nolimits --image nginx:1.27
kubectl autoscale deploy nolimits --min=1 --max=3 --cpu-percent=50
kubectl get hpa nolimits
kubectl describe hpa nolimits | grep -i -A2 warning

<unknown>/50% and FailedGetResourceMetric: missing request for cpu. Utilization is a percentage of the request.

Task B. You scale php-apache by hand to 5 replicas. What happens?

kubectl scale deploy php-apache --replicas 5
kubectl get hpa php-apache -w

The HPA owns replicas and brings it back to what the metric says.

Clean up

kubectl delete -f hpa.yaml
kubectl delete hpa nolimits --ignore-not-found
kubectl delete deploy php-apache nolimits --ignore-not-found
kubectl delete svc php-apache