Chapter 11: Autoscaling (HPA, VPA, KEDA)
- :material-school: **Topic Focus** • Horizontal, Vertical, and Event-Driven Workload Autoscaling
- :material-api: **Primary APIs** • `autoscaling/v2`, `keda.sh/v1alpha1` • `HorizontalPodAutoscaler`, `ScaledObject`
- :material-rocket-launch: [**Launch Playground in Wasm →**](../playground/index.html?chapter=11){ .md-button .md-button--primary }
⚡ Interactive Problems in this Chapter (Click to solve in Playground)
1. Architectural Overview & Control Plane Mechanics
In Kubernetes, Autoscaling (HPA, VPA, KEDA) is reconciled through declarative state loops managed by the control plane and node daemons:
flowchart TD
subgraph MetricsSource["Metrics Collection Pipeline"]
KSM["kube-state-metrics / cAdvisor"]
PROM["Prometheus / Datadog"]
METRICS_API["Custom Metrics API (k8s.io/metrics)"]
KSM --> METRICS_API
PROM --> METRICS_API
end
subgraph HorizontalScaling["Pod Autoscaling (HPA)"]
HPA["HPA Controller (15s Sync Period)<br/><code>Target: CPU 75%, Custom RPS 500</code>"]
METRICS_API -->|Query Live Utilization| HPA
DEPLOY["Deployment Controller<br/><i>Updates spec.replicas (3 ➔ 12)</i>"]
HPA -->|Desired Replicas Calculation| DEPLOY
end
subgraph NodeAutoscaling["Cluster Capacity Autoscaling"]
PENDING["Pods in Pending State (Insufficient CPU/Mem)"]
KARPENTER["Karpenter / Cluster Autoscaler"]
CLOUD["Cloud Provider (EC2 / GCE Instance Fleet)"]
DEPLOY -->|Surge Pods| PENDING
PENDING -->|Triggers Scaling Event| KARPENTER
KARPENTER -->|Provisions Right-Sized Node| CLOUD
end
1.1 Architectural Flow & Lifecycle Walkthrough
- Metrics Collection Pipeline:
cAdvisor(embedded insidekubelet) continuously collects Linux cgroup CPU and memory metrics, while external collectors (Prometheus, Datadog) scrape custom application metrics.metrics-serveraggregates these and exposes them via themetrics.k8s.iosubresource. - HPA Reconciler Evaluation: The Horizontal Pod Autoscaler (HPA) controller inside
kube-controller-managerqueries the Metrics API on a periodic sync loop (default: every 15 seconds). It calculates the desired replica count using the standard formula: $$\text{DesiredReplicas} = \left\lceil \text{CurrentReplicas} \times \left( \frac{\text{CurrentMetricValue}}{\text{TargetMetricValue}} \right) \right\rceil$$ - Scale Subresource Mutation: The HPA controller issues an HTTP
PATCHrequest to the target Deployment or StatefulSet's/scalesubresource, updatingspec.replicas. - Surge Pod Creation & Pending Capacity: The Deployment controller spins up new Pods. If the existing cluster worker nodes lack available CPU/memory allocatable capacity, the newly created Pods remain in
Pendingstate withPodReasonUnschedulable. - Cluster Capacity Scaling (Karpenter / Cluster Autoscaler):
- Karpenter: Subscribes directly to unschedulable Pod events via API watch, determines the optimal instance type (e.g. AWS
c6i.2xlargeor Spot instance) by evaluating Pod resource requests and topology spread constraints, and calls the cloud Fleet API to launch a right-sized node in under 45 seconds. - Cluster Autoscaler: Identifies pending pods, maps them to existing Node Groups / Auto Scaling Groups (ASGs), and increments the ASG desired capacity count.
1.2 Serialization, Protocols & Communication Pathways
- Prometheus OpenMetrics Exposition Format: Metrics scraped by Prometheus use plain-text or Protobuf-encoded OpenMetrics schemas over HTTP/1.1.
- Custom Metrics API Aggregator: The API server aggregates custom metric providers via the API Aggregator layer (
apiregistration.k8s.io/v1), proxying requests over TLS HTTP/2 to Prometheus Adapter or KEDA metrics servers. - Cloud Provider Fleet APIs: Karpenter and Cluster Autoscaler communicate with cloud compute APIs (AWS EC2
CreateFleet, GCP Compute Engine API) using signed HTTPS JSON/REST calls.
1.3 Deep-Dive Component Breakdown
- cAdvisor (Container Advisor): Daemon embedded inside
kubeletthat reads raw Linux kernel cgroups (/sys/fs/cgroup/cpu,/sys/fs/cgroup/memory) to expose container resource telemetry. - Horizontal Pod Autoscaler (HPA): Control loop calculating dynamic replica scaling based on CPU, memory, or custom Prometheus metrics with configurable stabilization windows.
- Vertical Pod Autoscaler (VPA): Controller that adjusts container
requestsandlimitsin-place or by recreating Pods to right-size long-term resource allocations. - Karpenter / Cluster Autoscaler: Infrastructure-level controllers that provision physical or virtual cloud worker instances in response to pending unschedulable workloads.
1.4 Under-The-Hood Mechanics & Failure Modes
- Autoscaling Thrashing & Flapping: Rapid spikes in traffic can cause HPA to aggressively scale replicas up and immediately down, destabilizing backend systems. Configuring
behavior.scaleDown.stabilizationWindowSeconds: 300enforces a cool-down buffer to prevent thrashing. - Missing Resource Requests: HPA utilization targets (e.g.,
averageUtilization: 70%) calculate percentage utilization strictly relative tospec.containers[*].resources.requests. If a container lacks resource requests, HPA cannot calculate the ratio and fails to scale. - HPA and VPA Mutual Conflict: Running HPA on CPU/memory targets concurrently with VPA on the same Deployment causes the two controllers to fight in a feedback loop (HPA scales replicas while VPA scales container sizes). Use VPA in
recommendationModeor run HPA on custom application metrics (e.g. RPS) when combining both.
2. Annotated Production YAML Anatomy & Field Reference
Below is a production-grade declarative manifest demonstrating field definitions and operational patterns:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-service
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 75
- type: Resource
resource:
name: memory
target:
type: AverageValue
averageValue: 200Mi
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
Key Field Schema Reference
| Field | Type | Description |
|---|---|---|
scaleTargetRef |
Object |
Target controller to scale (Deployment, ReplicaSet, StatefulSet). |
metrics[*].type |
Enum |
Resource (CPU/Memory via metrics-server), Pods (custom pod metrics), External (cloud queues/Prometheus). |
behavior.scaleDown.stabilizationWindowSeconds |
Integer |
Prevents thrashing (flapping) by damping scale-down operations for specified duration. |
3. Real-World Architectural Patterns
KEDA Event-Driven SQS Queue Scaler
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: sqs-worker-scaler
namespace: default
spec:
scaleTargetRef:
name: queue-worker
minReplicaCount: 1
maxReplicaCount: 20
triggers:
- type: aws-sqs-queue
metadata:
queueURL: https://sqs.us-east-1.amazonaws.com/123456789012/order-processing
queueLength: "10"
awsRegion: "us-east-1"
Custom Prometheus Metric HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: http-requests-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-frontend
minReplicas: 3
maxReplicas: 15
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: 1k
4. Production Hardening & Operational Governance
- All scaled containers MUST define explicit
resources.requests.cpuandresources.requests.memory; HPA cannot calculate percentages without requests. - Use
behavior.scaleDown.stabilizationWindowSeconds: 300to prevent premature scale-down during bursty traffic. - Avoid running HPA and VPA (Vertical Pod Autoscaler) on the same CPU/memory metrics simultaneously to prevent scaling contention.
5. Failure Modes & Diagnostic Triage Tree
HPA Status <unknown>/75%
Root Cause: Metrics Server is not installed or Pods lack CPU requests.
Diagnostic Triage Sequence:
1. Verify Metrics Server: kubectl get apiservices | grep metrics
2. Verify Pod metrics: kubectl top pods
3. Check HPA conditions: kubectl describe hpa <name>
6. Interactive Practice Matrix
Practice concepts from this chapter directly in the interactive WebAssembly sandbox:
| Exercise ID | Challenge Description | Direct Link | Action |
|---|---|---|---|
autoscale01 |
Horizontal Pod Autoscaler (HPA v2) | ../playground/index.html?exercise=autoscale01 |
⚡ Solve autoscale01 in Playground → |
autoscale02 |
HPA Custom Scaling Behavior | ../playground/index.html?exercise=autoscale02 |
⚡ Solve autoscale02 in Playground → |
autoscale03 |
Vertical Pod Autoscaler (VPA) | ../playground/index.html?exercise=autoscale03 |
⚡ Solve autoscale03 in Playground → |
autoscale04 |
Event-Driven Autoscaling (KEDA) | ../playground/index.html?exercise=autoscale04 |
⚡ Solve autoscale04 in Playground → |