Lab 42 - End-to-end production scenario
Lab 42 - End-to-end production scenario
InfodiscoverGoal: take an application to production with everything from the five days - then survive a game day. Chapter: Production operations and best practices
Work in pairs. Build everything in one file ~/prod-shop.yaml (plus the
Velero commands) so it can go to git.
The application
podinfo
ghcr.io/stefanprodan/podinfo:6.7.0 - port 9898, health /healthz,
readiness /readyz, metrics /metrics, message from env PODINFO_UI_MESSAGE.
Requirements
| # | Area | Requirement |
|---|---|---|
| 1 | Namespace | prod-shop, Pod Security restricted enforced; ResourceQuota (max 10 Pods, 2 CPU requests); LimitRange with defaults |
| 2 | Identity | own ServiceAccount shop, no API token mounted |
| 3 | Config | ConfigMap with PODINFO_UI_MESSAGE="Hello from GT"; Secret api-key injected as env API_KEY |
| 4 | Workload | Deployment, 3 replicas, non-root, read-only root FS, drop ALL, requests + memory limit, readiness + liveness |
| 5 | Availability | spread over nodes, PDB minAvailable: 2, HPA 3-6 replicas at 60 % CPU |
| 6 | Traffic | Service + HTTPRoute shop.prod.k8s.lab on traefik-gateway |
| 7 | Network | default-deny ingress; allow 9898 only from namespaces traefik and monitoring |
| 8 | Monitoring | ServiceMonitor; PrometheusRule alert when fewer than 2 replicas are available for 1 min |
| 9 | Backup | Velero schedule every 6 h, 3 days retention; one manual backup |
Check yourself:
kubectl get all,pdb,hpa,netpol,httproute,servicemonitor,prometheusrule -n prod-shop
curl -s -H 'Host: shop.prod.k8s.lab' http://worker01:30080 | grep -o '"message": "[^"]*"'
trivy config ~/prod-shop.yaml
velero backup get
Game day
Run a request loop in a second terminal the whole time and watch for errors:
while true; do curl -s -o /dev/null -w '%{http_code} ' -H 'Host: shop.prod.k8s.lab' http://worker01:30080; sleep 0.2; done
| # | Exercise | Expected |
|---|---|---|
| G1 | upgrade to podinfo:6.7.1 | only 200s during the rollout |
| G2 | drain the node with most shop Pods | only 200s; PDB respected; uncordon + rebalance afterwards |
| G3 | load test: kubectl run load -n prod-shop ... hammering the Service | HPA scales out, alert stays quiet |
| G4 | the trainer deletes namespace prod-shop | restore from Velero; measure your RTO from “404” to “200” |
| G5 | postmortem of G4 | timeline, RTO, what would make it faster (GitOps?) |
G3 load test inside the namespace needs a NetworkPolicy exception - or run the
load Pod in traefik… think about which is acceptable in production.
Reference solution
Wrap-up
What would you add before real production? Typical answers: GitOps (Argo CD)
instead of kubectl apply, secrets from a vault, OIDC logins, image signing,
a second environment, tested runbooks for every alert.
Clean up
kubectl delete ns prod-shop
velero schedule delete prod-shop --confirm