K8s PodDisruptionBudget PDB Guide
Configure Kubernetes PodDisruptionBudgets to protect application availability during node drains. minAvailable, maxUnavailable, and drain safety patterns.
π‘ Quick Answer:
PodDisruptionBudgetprevents too many pods from being evicted simultaneously during voluntary disruptions (node drain, cluster upgrades). SetminAvailable: 2(at least 2 pods must stay running) ormaxUnavailable: 1(at most 1 pod down at a time). Without a PDB,kubectl draincan evict all pods at once.
The Problem
Voluntary disruptions can kill your application:
kubectl drain nodeevicts all pods on a node- Cluster autoscaler scales down nodes with pods
- Kubernetes upgrades drain nodes one by one
- Without PDB, all replicas of a service could be evicted simultaneously
The Solution
Basic PDB
# At least 2 pods must always be running
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web-frontend
---
# At most 1 pod can be unavailable
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
spec:
maxUnavailable: 1
selector:
matchLabels:
app: api-service
---
# Percentage-based
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: worker-pdb
spec:
maxUnavailable: "25%"
selector:
matchLabels:
app: workerHow PDB Works
# Without PDB:
kubectl drain node-1
# All 3 replicas on node-1 evicted simultaneously β downtime!
# With PDB (maxUnavailable: 1):
kubectl drain node-1
# Pod 1 evicted β rescheduled on node-2 β becomes Ready
# Pod 2 evicted β rescheduled on node-3 β becomes Ready
# Pod 3 evicted β rescheduled β done
# At most 1 pod unavailable at any time β no downtime!Check PDB Status
kubectl get pdb
# NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
# web-pdb 2 N/A 1 5m
# api-pdb N/A 1 1 5m
kubectl describe pdb web-pdb
# Status:
# Current Healthy: 3
# Desired Healthy: 2
# Disruptions Allowed: 1PDB + Node Drain
# Drain respects PDBs
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
# If PDB blocks drain:
# error when evicting pods: Cannot evict pod as it would violate the pod's disruption budget.
# Force drain (ignores PDB β use with caution!)
kubectl drain node-1 --ignore-daemonsets --force
# Timeout drain
kubectl drain node-1 --ignore-daemonsets --timeout=300sminAvailable vs maxUnavailable
| Setting | 3 replicas | 5 replicas | Best for |
|---|---|---|---|
minAvailable: 1 | 2 can be down | 4 can be down | Minimum viable |
minAvailable: 2 | 1 can be down | 3 can be down | High availability |
maxUnavailable: 1 | 2 must stay | 4 must stay | Most common |
maxUnavailable: "50%" | 1 can be down | 2 can be down | Large deployments |
Common Patterns
# Stateless web app β allow 1 down at a time
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
maxUnavailable: 1
selector:
matchLabels:
app: web
---
# Database β never disrupt the primary
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: db-pdb
spec:
minAvailable: 1 # Primary must always be up
selector:
matchLabels:
app: postgres
role: primary
---
# Batch workers β allow more disruption
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: worker-pdb
spec:
maxUnavailable: "50%"
selector:
matchLabels:
app: batch-workerCommon Issues
Drain blocked indefinitely by PDB
Only 1 replica and minAvailable: 1 β can never evict. Use maxUnavailable: 1 instead, or increase replicas.
PDB not protecting pods
Selector doesnβt match pod labels. Check: kubectl get pdb -o yaml and compare with kubectl get pods --show-labels.
PDB blocks cluster autoscaler scale-down
By design β autoscaler respects PDBs. Ensure enough replicas spread across nodes so at least one node can always be drained.
Best Practices
- Every production Deployment should have a PDB β protect against drain
- Use
maxUnavailable: 1as the default β simple and safe - Never set
minAvailableequal toreplicasβ blocks all disruptions - Spread replicas across nodes with pod anti-affinity β PDB + spread = safe drains
- Test with
kubectl drain --dry-run=serverβ preview what would be evicted
Key Takeaways
- PDBs protect pods during voluntary disruptions (drain, autoscaler, upgrades)
maxUnavailable: 1is the most common and safest default- Without PDB,
kubectl draincan evict all replicas simultaneously - PDBs donβt protect against involuntary disruptions (node crash, OOM)
- Combine with pod anti-affinity for full high-availability protection

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
