Title: Lab 9 — Autoscaling a CPU-Bound App with HPA
Course: AIINFRA 101: Applied Infrastructure & Containerization > Section: Week 09 — Scaling & GPU-Aware Scheduling: HPA and the NVIDIA GPU Operator

🛠️ Lab 9 — Autoscaling a CPU-Bound App with HPA (50 pts)

Goal: Deploy a CPU-consuming app on your local kind/minikube cluster, install Metrics Server, create an HPA targeting 50% CPU utilization, generate sustained load, and observe HPA scale replicas up and down live — including the 1–2 minute reaction delay.

Steps:

1. Confirm your cluster from Weeks 6–8 is running: kubectl cluster-info.
2. Install Metrics Server: kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml. On kind/minikube, if the pod won't go Ready due to local TLS checks, patch the Deployment to add --kubelet-insecure-tls — normal for local clusters, not a production practice.
3. Verify with kubectl top nodes and kubectl top pods -A before proceeding — both must return real numbers.
4. Deploy the official php-apache CPU-load example (or a simple Flask app with a /generate-load endpoint). Set resources.requests.cpu: 100m explicitly — HPA has nothing to calculate a percentage against otherwise.
5. Expose it with a ClusterIP Service.
6. Create the HPA: kubectl autoscale deployment <name> --cpu-percent=50 --min=1 --max=10 (or the equivalent autoscaling/v2 YAML).
7. In a second terminal, watch it live: kubectl get hpa -w, and leave it running.
8. In a third terminal, generate sustained load: kubectl run -it load-generator --image=busybox --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://<service-name>; done".
9. Note the timestamp load started, when TARGETS first exceeds 50%, and when REPLICAS first increases — that gap is your observed reaction delay.
10. Delete the load generator and keep watching until replicas scale back down, noting how much longer scale-down takes (the stabilization window in action).
11. Capture: the Metrics Server verification, your HPA manifest/command, the annotated kubectl get hpa -w output for both events, and a 150–250 word note explaining the delay and the role of resource requests.

Optional GPU extension (if you have access to a GPU node): Install the NVIDIA GPU Operator (helm install --wait --generate-name -n gpu-operator --create-namespace nvidia/gpu-operator --version=v26.3.3), confirm nvidia.com/gpu appears in kubectl get nodes -o json | jq '.items[].status.capacity', and run a one-GPU Job using the nvidia/cuda:12.4.1-base-ubuntu22.04 image to confirm nvidia-smi output in its logs. Attach this as a bonus section — it is not required for full credit.

Deliverables: A short lab report (PDF or text) with your HPA manifest/command, the annotated kubectl get hpa -w output/screenshots, and your written explanation, uploaded to this assignment.