0 / 15 lessons — 0%
Lesson 14 / 15

Autoscaling & scheduling: HPA, affinity, taints & tolerations

kubectl scale works, but someone has to be watching and typing it. This lesson covers letting Kubernetes make that call itself — and steering where pods land once it does.

Horizontal Pod Autoscaler (HPA)

An HPA watches a metric (CPU usage by default) and adjusts a Deployment's replica count automatically to keep it near a target.

# the quick way kubectl autoscale deployment web --min=2 --max=10 --cpu-percent=70 # the declarative way — hpa.yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: web spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: { type: Utilization, averageUtilization: 70 }

Watch it in action with kubectl get hpa — under load, the replica count climbs on its own; once load drops, it scales back down.

Node affinity — pods that prefer (or require) certain nodes

Some pods have real reasons to prefer specific nodes — a GPU workload needs a GPU node; a latency-sensitive service might want to stay in one availability zone. Node affinity lets a pod's spec require or merely prefer nodes matching certain labels.

affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: gpu operator: In values: ["true"]

Taints & tolerations — the opposite direction

Affinity is a pod saying "I want that node." A taint is a node saying "stay away unless you're specifically allowed" — control-plane nodes are taints by default, which is why your regular app pods never accidentally land on them. A pod only schedules onto a tainted node if it carries a matching toleration.

# taint a node — nothing schedules here unless it tolerates this kubectl taint nodes gpu-node-1 gpu=true:NoSchedule
# in the pod spec — the "permission slip" that lets it land there tolerations: - key: gpu operator: Equal value: "true" effect: NoSchedule
The distinction in one line: affinity is attraction, taints are repulsion, and tolerations are what override a repulsion. A pod needs a matching toleration just to be considered for a tainted node — affinity (or nothing at all) still decides whether it actually lands there among other untainted options.
Try it yourselfRun kubectl describe node on any control-plane node in a real cluster and look at the Taints field near the top — that's the exact mechanism keeping your everyday workloads off of it.