Amazon EKS — Auto Scaling — Practice Exercises
Chapter 11 — Practice Exercises
Exercise 1: HPA Configuration
Question: Create an HPA that scales a Deployment called api from 3 to 30 replicas based on: CPU at 60%, memory at 75%, with a 5-minute cooldown on scale-down.
Show Solution
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
Exercise 2: Karpenter vs Cluster Autoscaler
Question: Compare Karpenter and Cluster Autoscaler for a cluster with: varied workloads (small to large), cost optimization needed, and fast scaling required. Which would you choose and why?
Show Solution
Choose Karpenter.
| Requirement | Cluster Autoscaler | Karpenter |
|---|---|---|
| Varied workloads | Need multiple node groups | Single NodePool handles all |
| Cost optimization | Fixed instance types per group | Right-sizes per pod |
| Fast scaling | 1-3 min (ASG + bootstrap) | 30-60 sec (direct EC2) |
| Consolidation | Manual | Automatic |
Karpenter advantages for this use case:
- Automatically picks the cheapest instance that fits each workload
- Spot + On-Demand mixed without separate node groups
- Consolidation reduces waste during off-peak
- Faster because it doesn’t go through ASG
Exercise 3: Scaling Architecture
Question: Design the complete scaling architecture for an e-commerce site with: steady web traffic (2x peaks during sales), order processing queue (SQS), and a cron job running at midnight.
Show Solution
# 1. Web frontend — HPA based on CPU
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
name: web
minReplicas: 5
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
averageUtilization: 60
# 2. Order processing — KEDA based on SQS
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: order-worker
spec:
scaleTargetRef:
name: order-worker
minReplicaCount: 1
maxReplicaCount: 100
triggers:
- type: aws-sqs-queue
metadata:
queueURL: https://sqs.../orders
queueLength: "10"
# 3. Cron job — KEDA cron scaler
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: batch-job
spec:
scaleTargetRef:
name: batch-worker
minReplicaCount: 0
maxReplicaCount: 10
triggers:
- type: cron
metadata:
timezone: America/New_York
start: 0 0 * * *
end: 0 2 * * *
desiredReplicas: "10"
# 4. Nodes — Karpenter for all
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
disruption:
consolidationPolicy: WhenUnderutilized
Exercise 4: Troubleshoot Scaling
Question: HPA shows <unknown>/50% for CPU target. Pods are not scaling. What’s wrong?
Show Solution
Most likely cause: Missing resource requests on the pod.
HPA calculates CPU utilization as a percentage of the requested CPU. Without requests, there’s no baseline to calculate against.
# Check if metrics server is running
$ kubectl top pods
# If error: install metrics server
# Check pod resource requests
$ kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[0].resources}'
# If empty: add resource requests
# Fix: add resource requests
spec:
containers:
- name: web
resources:
requests:
cpu: 100m
memory: 128Mi
Other causes: metrics server not installed, or RBAC blocking metrics API access.
Exercise 5: Cost vs Performance
Question: Your cluster uses Cluster Autoscaler with 3 fixed node groups (m5.large). During a traffic spike, it takes 4 minutes for new pods to start serving traffic. How would you reduce this to under 1 minute?
Show Solution
Three-pronged approach:
- Over-provision with pause pods:
apiVersion: apps/v1 kind: Deployment metadata: name: overprovisioner spec: replicas: 2 template: spec: priorityClassName: overprovisioner # Low priority containers: - name: pause image: registry.k8s.io/pause resources: requests: cpu: 1 memory: 2GiWhen real pods need space, pause pods are evicted instantly → pods schedule on existing nodes (seconds, not minutes).
-
Switch to Karpenter: Karpenter launches EC2 directly (no ASG), cutting provisioning from ~3 min to ~30 sec.
- Increase HPA min replicas: More baseline pods = less scaling needed during spikes.
Combined result: Scale-up in 10-30 seconds instead of 4 minutes.
What’s Next?
Monitor everything: Chapter 12 — Observability.