What Are Pod Disruption Budgets (PDBs)?

advanced|podsdevopssreCKA
TL;DR

A Pod Disruption Budget (PDB) limits the number of Pods of a replicated application that can be voluntarily disrupted at any given time. PDBs ensure that a minimum number of Pods remain available during maintenance operations like node drains, cluster upgrades, or autoscaler scale-downs.

Detailed Answer

A Pod Disruption Budget (PDB) is a Kubernetes resource that limits the number of Pods of a replicated application that can be taken down simultaneously during voluntary disruptions. PDBs are critical for maintaining application availability during cluster maintenance.

Voluntary vs. Involuntary Disruptions

Voluntary disruptions are planned, controlled events:

  • kubectl drain (node maintenance)
  • Cluster autoscaler removing underutilized nodes
  • Kubernetes version upgrades
  • Rolling updates on Deployments

Involuntary disruptions are unplanned events:

  • Node hardware failure
  • Kernel panic
  • Network partition
  • OOM kills

PDBs only protect against voluntary disruptions. They cannot prevent hardware failures or OOM kills.

Creating a PDB

You can specify either minAvailable or maxUnavailable (but not both):

Using minAvailable

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app-pdb
  namespace: production
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web-app

This PDB guarantees that at least 2 Pods matching app: web-app remain available at all times during voluntary disruptions.

Using maxUnavailable

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app-pdb
  namespace: production
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      app: web-app

This PDB allows at most 1 Pod to be unavailable during voluntary disruptions.

Using Percentages

Both fields accept percentages:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app-pdb
spec:
  maxUnavailable: "25%"
  selector:
    matchLabels:
      app: web-app

For a Deployment with 4 replicas, this allows 1 Pod (25% of 4, rounded down) to be unavailable.

How PDBs Interact with Node Drains

When you run kubectl drain, the drain process uses the Eviction API, which respects PDBs:

# Drain a node for maintenance
kubectl drain node01 --ignore-daemonsets --delete-emptydir-data

# If a PDB blocks the drain:
# evicting pod production/web-app-abc12
# error when evicting pods/"web-app-abc12" -n "production" (will retry):
#   Cannot evict pod as it would violate the pod's disruption budget.

# The drain will keep retrying until PDB allows eviction or you cancel

The drain process evicts Pods one at a time, waiting for replacement Pods to become ready before evicting more.

PDB Status

Check the current status of a PDB:

kubectl get pdb web-app-pdb -o wide
# NAME          MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
# web-app-pdb   2               N/A               1                     30m

kubectl describe pdb web-app-pdb
# Look for:
# - Allowed disruptions: how many Pods can currently be evicted
# - Current healthy: how many matching Pods are healthy right now
# - Desired healthy: minimum Pods that must remain healthy

PDB Calculation Examples

| Replicas | PDB Setting | Allowed Disruptions | |----------|-------------|-------------------| | 5 | minAvailable: 3 | 2 | | 5 | maxUnavailable: 2 | 2 | | 3 | minAvailable: 3 | 0 (blocks all evictions) | | 3 | maxUnavailable: 0 | 0 (blocks all evictions) | | 4 | maxUnavailable: "25%" | 1 | | 1 | minAvailable: 1 | 0 (blocks all evictions) |

Warning: Setting minAvailable equal to the replica count or maxUnavailable: 0 blocks all voluntary disruptions, which prevents node drains and cluster upgrades.

PDB and Rolling Updates

During a Deployment rolling update, the Deployment controller creates and terminates Pods. The rolling update process respects PDBs -- if evicting a Pod would violate the PDB, the update pauses until conditions allow it to proceed.

This interaction means your PDB settings, maxSurge, and maxUnavailable in the Deployment's update strategy must be compatible:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  # ...
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-app-pdb
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      app: web-app

Unhealthy Pod Eviction Policy

Kubernetes 1.31 introduced the unhealthyPodEvictionPolicy field (stable) that controls how unhealthy Pods count against the PDB:

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

| Policy | Behavior | |--------|----------| | IfHealthy (default) | Unhealthy Pods count against the budget, may block drains | | AlwaysAllow | Unhealthy Pods can always be evicted, preventing stuck drains |

AlwaysAllow is recommended when stuck or unhealthy Pods should not block node maintenance.

Best Practices

  1. Create PDBs for all production workloads with more than one replica.
  2. Never set maxUnavailable: 0 or minAvailable equal to replica count in production -- this blocks all maintenance operations.
  3. Use maxUnavailable: 1 as a sensible default for most services.
  4. Use percentages for large Deployments to allow proportional disruption.
  5. Pair PDBs with readiness probes so Kubernetes knows which Pods are truly healthy.
  6. Set unhealthyPodEvictionPolicy: AlwaysAllow to prevent unhealthy Pods from blocking node drains.
  7. Test PDBs before maintenance by checking kubectl get pdb to verify that allowed disruptions are greater than zero.

Why Interviewers Ask This

This question tests whether you can maintain application availability during cluster operations. PDBs are a key mechanism for zero-downtime maintenance, and interviewers want to know you can configure them correctly.

Common Follow-Up Questions

What is the difference between voluntary and involuntary disruptions?
Voluntary disruptions are intentional actions like node drains, cluster upgrades, and autoscaler decisions. Involuntary disruptions are unplanned events like hardware failures or kernel panics. PDBs only protect against voluntary disruptions.
What happens if a PDB prevents a node drain?
The kubectl drain command will block, respecting the PDB. After the configured timeout (--timeout flag), it can be forced with --disable-eviction, but this bypasses PDB protection.
Can you set both minAvailable and maxUnavailable?
No. You must choose one or the other. Setting both in the same PDB is not allowed.

Key Takeaways

  • PDBs protect against voluntary disruptions only (drains, upgrades, autoscaling).
  • Use minAvailable to guarantee a minimum number of running Pods, or maxUnavailable to cap how many can be down.
  • PDBs are essential for zero-downtime cluster maintenance.

Related Questions