πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Deployments intermediate ⏱ 8 minutes K8s 1.28+

K8s PodDisruptionBudget PDB Guide

Configure Kubernetes PodDisruptionBudgets to protect application availability during node drains. minAvailable, maxUnavailable, and drain safety patterns.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: PodDisruptionBudget prevents too many pods from being evicted simultaneously during voluntary disruptions (node drain, cluster upgrades). Set minAvailable: 2 (at least 2 pods must stay running) or maxUnavailable: 1 (at most 1 pod down at a time). Without a PDB, kubectl drain can evict all pods at once.

The Problem

Voluntary disruptions can kill your application:

  • kubectl drain node evicts 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: worker

How 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: 1

PDB + 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=300s

minAvailable vs maxUnavailable

Setting3 replicas5 replicasBest for
minAvailable: 12 can be down4 can be downMinimum viable
minAvailable: 21 can be down3 can be downHigh availability
maxUnavailable: 12 must stay4 must stayMost common
maxUnavailable: "50%"1 can be down2 can be downLarge 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-worker

Common 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: 1 as the default β€” simple and safe
  • Never set minAvailable equal to replicas β€” 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: 1 is the most common and safest default
  • Without PDB, kubectl drain can evict all replicas simultaneously
  • PDBs don’t protect against involuntary disruptions (node crash, OOM)
  • Combine with pod anti-affinity for full high-availability protection
#pdb #availability #node-drain #scheduling #cka
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens