Amazon EKS — Auto Scaling — Practice Exercises

3 minute read

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:

  1. 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: 2Gi
    

    When real pods need space, pause pods are evicted instantly → pods schedule on existing nodes (seconds, not minutes).

  2. Switch to Karpenter: Karpenter launches EC2 directly (no ASG), cutting provisioning from ~3 min to ~30 sec.

  3. 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.