Handbooks / Kubernetes / Chapter 5

Scaling and Health

7 pages · ~5 min✓ Reviewed

Builds on Storage.

KubernetesPage 1

Probes and Resources: The Mental Model

1. Who Decides What

  • Probes: kubelet health checks on a container
  • Requests and limits: scheduler and kernel contract
  • HPA: changes the replica count
  • Together: pod is placed, kept alive, sent traffic

2. Probes

ProbeOn failure
Livenesskubelet restarts the container
Readinessremoved from Service endpoints, not restarted
Startupholds off liveness and readiness until booted
  • httpGet: 2xx/3xx passes
  • tcpSocket: port opens
  • exec: exit code 0
  • grpc: gRPC health check
  • Each probe runs on its own periodSeconds timer

3. Requests vs Limits

Effect
Requestsscheduler reserves them when placing the pod
Limitsenforced at runtime: CPU throttled, memory OOMKilled

4. Interview Point

  • Liveness vs readiness? Liveness restarts the container; readiness only stops traffic
  • Slow-starting app? A startup probe
  • Readiness fails? Pod leaves Service endpoints: no traffic, no restart
KubernetesPage 2

Configuring Probes Correctly

1. Key Fields

FieldDefaultMeaning
initialDelaySeconds0wait before first probe
periodSeconds10gap between probes
timeoutSeconds1max wait per probe
successThreshold1passes to recover
failureThreshold3fails before action
  • Startup budget = failureThreshold x periodSeconds, e.g. 30 x 10 = 300s to boot

2. Which Probe Asks What

ProbeAsksGates endpoints?
LivenessShould I restart?no
ReadinessShould I get traffic?yes
StartupHas it finished booting?no
yaml
readinessProbe:
  httpGet:
    path: /healthz
    port: 8080
  periodSeconds: 5
  failureThreshold: 3

3. Mistakes

  • Liveness checks a database or dependency: cascading restarts
  • Short timeoutSeconds on a slow app: restart loop
  • Big initialDelaySeconds: use a startup probe instead

4. Interview Point

  • Liveness and dependencies? Never: one outage restarts every pod
  • Size a startup probe? failureThreshold x periodSeconds above worst boot time
  • Default failureThreshold? 3
KubernetesPage 3

Requests, Limits and QoS Classes

1. CPU vs Memory

CPUMemory
Unitcores / millicores (500m = 0.5)Mi / Gi
Typecompressibleincompressible
Over limitthrottledOOMKilled, exit 137
yaml
resources:
  requests:
    cpu: 250m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi

requests reserve, limits enforce

2. QoS and Scheduling

ClassRuleEvicted
Guaranteedrequests = limits, every container, CPU + memorylast
Burstableat least one request or limit setsecond
BestEffortnone setfirst
  • Scheduler counts requests only
  • Pending: no node with enough unreserved allocatable

3. Common Mistakes

  • No requests: HPA cannot compute CPU utilization
  • CPU limit too low: silent latency from throttling
  • Memory limit below working set: repeated OOMKills
KubernetesPage 4

Horizontal Pod Autoscaler

1. The Formula

  • desired = ceil(current × currentMetric / target)
  • Checks about every 15s; needs metrics-server
  • CPU % is measured against requests, not limits
  • No CPU request → metric shows <unknown>, no scaling

2. Create and Tune

bash
kubectl autoscale deployment web --cpu-percent=70 --min=2 --max=10

or an autoscaling/v2 HorizontalPodAutoscaler

  • v2 YAML: minReplicas, maxReplicas, metrics list
  • Scale-down waits a 300s stabilization window (default)
  • Scale-up reacts faster; tune both in spec.behavior

3. Who Scales What

ToolChangesTrigger
HPApod countmetric vs target
VPApod requests and limitsobserved usage
Cluster Autoscalernode countPending pods
KubernetesPage 5

Troubleshooting CrashLoopBackOff, Pending and ImagePullBackOff

1. Reading the Status

StatusWhat happensFirst check
CrashLoopBackOffStarts, exits, restarts: 10s, 20s, 40s, max 5mlogs --previous
PendingNot scheduleddescribe pod Events
ImagePullBackOffPull fails, retried with backoffImage reference
  • Exit 1 app error, 137 OOMKilled/SIGKILL, 143 SIGTERM
  • Confirm OOM: describe pod Last State shows Reason: OOMKilled
  • Also check whether the liveness probe kills it
  • Pending: Insufficient cpu, untolerated taints, selector mismatch, unbound PVC
  • Pull: wrong name or tag, no imagePullSecrets, rate limits

2. Triage Order

  1. get podread status
  2. describe podEvents at bottom
  3. logs--previous if crashed
  4. get events--sort-by=.lastTimestamp

3. Mistakes

  • Reading current logs of a restarting pod, not --previous
  • Guessing resources instead of kubectl top pod
  • Readiness failure shows 0/1 Ready with no restarts

4. Interview Point

  • Pending first? describe pod Events
  • OOMKilled or app crash? Last State Reason OOMKilled; exit 1 is the app
  • Why back off? Growing restart delay stops a tight crash loop wasting node CPU; pull retries spare the registry
KubernetesPage 6

Probes, Resources, HPA and Troubleshooting Cheat Sheet

1. Probes and Resources

  • Liveness restarts the container
  • Readiness gates Service traffic
  • Startup protects slow boots: budget = failureThreshold x periodSeconds
  • Scheduler uses requests; kernel enforces limits
  • CPU over limit: throttled. Memory over limit: OOMKilled (137)
QoSRule
Guaranteedrequests = limits
Burstablesome request or limit set
BestEffortnone set, evicted first

2. HPA

  • ceil(current x currentMetric / target)
  • Needs metrics-server and CPU requests
  • Scale-down window: 300s by default
bash
kubectl autoscale deployment web --cpu-percent=70 --min=2 --max=10

3. Debug and Status Causes

bash
kubectl describe pod X
kubectl logs X --previous
kubectl get events --sort-by=.lastTimestamp
kubectl top pod
StatusCause
CrashLoopBackOffapp or liveness probe kills container
Pendingno schedulable node or unbound PVC
ImagePullBackOffbad image name or missing pull secret
Interview Point

Not serving traffic? describe, then logs --previous, then events. Pending = scheduling; CrashLoopBackOff, ImagePullBackOff = container.

KubernetesPage 7

Check yourself

A pod shows 0/1 Ready, status Running, RESTARTS 0. Which probe is failing, and where is its traffic going?
  • The readiness probe is failing.
  • The pod leaves the Service endpoints. It is not restarted, so traffic goes to the other pods.
A startup probe has failureThreshold 30 and periodSeconds 10. The app needs 400s to boot. What happens?
  • The budget is 30 x 10 = 300s, so the probe fails first.
  • kubelet restarts the container, and it loops. Raise failureThreshold to 40 or more.
An HPA targets 60% CPU. 4 replicas run at 90% of their requests. How many replicas does it want?
  • ceil(4 x 90 / 60) = ceil(6) = 6 replicas.