Pod Disruption Budgets: Keeping Services Up During Cluster Maintenance
A node drain can take your whole service down if you let it. Pod Disruption Budgets tell Kubernetes how much availability it must preserve.
- #kubernetes
- #pdb
- #availability
- #reliability
- #node-maintenance
- #sre
I once watched a routine cluster upgrade take down a “highly available” service with three replicas. The reason was embarrassingly simple: a node drain during the rolling upgrade evicted all three pods at roughly the same time, because nothing told Kubernetes it wasn’t allowed to. A PodDisruptionBudget would have prevented it in four lines of YAML. If you run anything you care about on Kubernetes and you don’t have PDBs, this is the cheapest reliability win available to you.
Voluntary vs. involuntary disruptions
The distinction is the whole concept. Kubernetes splits pod disruptions into two buckets:
- Involuntary — a node hardware failure, a kernel panic, an OOM kill. Nobody chose this; PDBs can’t help.
- Voluntary — a node drain for an upgrade, a cluster-autoscaler scale-down, a
kubectl drainfor maintenance. Someone (or something) chose to evict pods.
A PodDisruptionBudget governs voluntary disruptions only. It’s a contract with the eviction API: “you may evict pods from this set, but you must always leave at least N available.” When a drain would violate that, the eviction blocks and waits.
A minimal PDB
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
namespace: web
spec:
minAvailable: 2
selector:
matchLabels:
app: api
This says: across all pods labeled app: api, never let voluntary evictions drop you below 2 available. If you have 3 replicas and a node drains, Kubernetes evicts one, waits for the replacement to be Ready elsewhere, then evicts the next. The service stays up throughout.
minAvailable vs. maxUnavailable
You can express the budget either way:
minAvailable: 2— keep at least 2 pods up.maxUnavailable: 1— let at most 1 pod be down at a time.
For most rolling-friendly services I prefer maxUnavailable, often as a percentage:
spec:
maxUnavailable: 25%
Percentages scale with your replica count, so the same PDB behaves sensibly whether the deployment is at 4 replicas or 40. The one rule: pick one field, not both — setting both is invalid.
The trap that wedges your drains
Here’s the failure I see constantly. Someone writes minAvailable: 3 for a deployment that has exactly 3 replicas. Now a node drain can never evict a single pod, because doing so would drop available below 3. The drain hangs forever, the upgrade stalls, and an on-call engineer eventually force-deletes pods to break the deadlock — defeating the whole point.
The rule: your PDB must leave the scheduler room to move. If you run N replicas, minAvailable must be less than N (or maxUnavailable at least 1). For 3 replicas, minAvailable: 2 or maxUnavailable: 1. Never minAvailable: 3.
Verify before you trust it:
kubectl get pdb -n web
NAME MIN AVAILABLE ALLOWED DISRUPTIONS AGE
api-pdb 2 1 5m
ALLOWED DISRUPTIONS is the number that matters. If it’s 0 when all pods are healthy, your budget is too strict and drains will hang. It should be at least 1.
PDBs and single-replica workloads
A PDB on a one-replica deployment is a contradiction: you can’t both keep it available and ever evict it. For singletons, the honest answer is that they’re not highly available, and a node drain will cause a brief outage. Either run more replicas or accept the gap — don’t paper over it with a PDB that just makes drains hang.
Where PDBs really earn their keep
Three scenarios where a PDB turns a potential incident into a non-event:
- Cluster upgrades. Managed Kubernetes upgrades drain nodes one at a time. PDBs make that drain respect your availability instead of yanking all replicas on a crowded node together.
- Cluster autoscaler scale-down. When the autoscaler wants to remove an underutilized node, it drains it first. Without a PDB it can consolidate your replicas off a node in one move. With one, it proceeds politely.
- Spot/preemptible node pools. Combined with graceful termination, PDBs keep capacity stable as cheaper nodes come and go.
Pair it with topology, not just count
A PDB guarantees how many pods stay up, but not where they run. If all three of your replicas landed on the same node, a single involuntary node failure still takes you down — and the PDB never had a say, because that’s an involuntary disruption. PDBs are necessary but not sufficient; pair them with topology spread constraints or anti-affinity so your replicas are actually distributed across nodes and zones.
A checklist before you call a service HA
- At least 2 replicas (ideally 3) — a PDB on 1 is meaningless.
- A PDB with
ALLOWED DISRUPTIONS >= 1when healthy. - Replicas spread across nodes/zones, not stacked.
- Readiness probes that actually reflect “can serve traffic,” so the eviction flow waits for a real replacement.
That last point is subtle: the eviction API leans on readiness to know when it’s safe to evict the next pod. A lying readiness probe makes your PDB lie too.
Before you roll PDBs across a cluster, it’s worth a review pass to catch the minAvailable == replicas trap, which is easy to write and hard to notice until a drain hangs at 2am. Our AI code review flags PDBs that would block all evictions.
PodDisruptionBudgets are four lines of YAML that stand between a routine upgrade and an outage. For more reliability and operations guides, see the Kubernetes & Helm category.
Disruption budgets only govern voluntary evictions. Validate replica counts and allowed-disruption numbers against your own availability targets before relying on them.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.