Kubernetes PodDisruptionBudget + Eviction API Playbook

2026-03-29 · software

Kubernetes PodDisruptionBudget + Eviction API Playbook

How to make node maintenance, autoscaling, and upgrades boring instead of outage-prone.

Why this matters

Most Kubernetes incidents during maintenance are not caused by a broken rollout script—they come from mismatch between workload availability assumptions and disruption controls.

Typical failure pattern:

  1. Team sets an overly strict PDB (maxUnavailable: 0 or minAvailable: 100%)
  2. Node drain starts
  3. Evictions are rejected forever (429), maintenance pipelines hang
  4. Operators bypass with force-delete, causing avoidable downtime

This playbook gives a practical operating model to avoid that trap.


1) Mental model: three different “unavailability budgets”

You need to reason about three separate controls:

  1. Workload rollout budget (e.g., Deployment maxUnavailable, maxSurge)
    • Controls app updates from controller strategy.
  2. Disruption budget (PDB minAvailable or maxUnavailable)
    • Controls voluntary evictions via Eviction API (drain, autoscaler, managed upgrades).
  3. Involuntary failure budget (node crash, kernel panic, AZ loss)
    • Not preventable by PDB; but involuntary loss still counts against current availability.

Key nuance: PDB does not govern all pod removals. Direct deletes can bypass it.


2) Ground rules (non-negotiable)

Rule A — Never use “zero voluntary eviction” by accident

These settings can make drains impossible by design.

Rule B — Prefer maxUnavailable for elastic workloads

For many replicated services, maxUnavailable: 1 is safer operationally than fixed minAvailable because it scales with replica count changes.

Rule C — Set unhealthy pod eviction behavior intentionally

Use:

unhealthyPodEvictionPolicy: AlwaysAllow

Why: default behavior can block drains when pods are running but not Ready (CrashLoopBackOff, broken probes, etc.).

Rule D — Use Eviction API path for maintenance

kubectl drain (without --disable-eviction) respects PDB and graceful termination. Direct DELETE is a last-resort break-glass path.


3) PDB design recipes by workload type

A) Stateless API / web tier

B) Quorum systems (etcd, ZooKeeper-like)

C) Singleton stateful workload

D) Batch / replaceable jobs


4) Interlock: Deployment rolling update vs PDB

A common confusion:

These are independent levers. If both are too strict, you can deadlock operations.

Practical heuristic:


5) Node drain runbook (production-safe)

Preflight

  1. Confirm target node pod mix:
    kubectl get pods -A -o wide --field-selector spec.nodeName=<node>
    
  2. Confirm PDB headroom:
    kubectl get pdb -A
    
  3. Watch allowed disruptions + readiness for critical namespaces.

Drain

kubectl drain <node> --ignore-daemonsets --delete-emptydir-data --timeout=30m

Notes:

During drain

Restore

kubectl uncordon <node>

6) Failure modes and fast fixes

Symptom: drain hangs forever

Likely causes:

Fix order:

  1. Add temporary capacity
  2. Repair unhealthy rollout/probes
  3. Adjust PDB to realistic threshold
  4. Use direct delete only with explicit incident decision

Symptom: Eviction API returns 429 repeatedly

Interpretation:

Actions:

Symptom: Eviction API returns 500

Interpretation:

Actions:


7) Baseline manifests

PDB for stateless service

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: api-pdb
spec:
  maxUnavailable: 1
  unhealthyPodEvictionPolicy: AlwaysAllow
  selector:
    matchLabels:
      app: api

Deployment alignment example

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 1
    maxSurge: 1

This pairing usually yields predictable updates + maintainable drains.


8) Operational SLO checks (recommended)

Track these continuously:

If break-glass deletions become normal, your disruption model is wrong.


9) Compact checklist

Before enabling automated node maintenance:


References