Skip to main content

Add a PodDisruptionBudget

Inspect 1.36

A PodDisruptionBudget caps how many pods of one application can be down at once during a voluntary disruption, such as the node drains that happen on every Kubernetes upgrade and repair. Without one, a drain can evict your last pod and take the application offline. With one, the drain waits.

Get one wrong and it fails in two directions, both only visible mid-maintenance: a budget with no slack, or one too tight to satisfy.

What a PDB does and does not protect#

A PDB protects against voluntary disruptions: node drains, and anything else that asks Kubernetes to move a pod politely. It does not protect against a node crash or hardware failure, because nothing asks permission there. So a PDB is no substitute for running enough replicas: replicas are the floor, and the PDB just meters how fast a drain works through them.

minAvailable or maxUnavailable#

Pick exactly one:

yaml
		apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web
spec:
  maxUnavailable: 1 # or: minAvailable: 2
  selector:
    matchLabels:
      app: web
	

maxUnavailable: 1 lets a drain take at most one pod at a time, the right default for a horizontally scaled service. minAvailable: 2 keeps a fixed number serving no matter what. Either way, match the number to your replica count: three replicas with maxUnavailable: 1 leaves two up throughout a rolling drain. And put the pods on different nodes, or the budget has nothing to spread. See .

Why ALLOWED DISRUPTIONS reads 0#

		$ kubectl get pdb -n team-web web
NAME   MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
web    N/A             1                 1                     2m
	

ALLOWED DISRUPTIONS is how many pods may be evicted right now. If it reads 0 when you expect 1, a pod is currently not ready, so the budget has no slack to give. A drain then waits for that pod to recover. A 0 that never climbs means a pod is stuck. Fix its readiness before the next maintenance, not during it.

When a drain hangs and will not finish#

The other symptom looks like a hang. The drain grinds through the full 180 seconds, then evicts the pod anyway, because the budget was set too tight to ever satisfy. A drain waits only as long as nodeDrainTimeoutSeconds allows, a per-pool default of 180 seconds that is in the Cluster topology. After that it proceeds, and the pods on that node go with it. A PDB provides an orderly, one-at-a-time move, never an indefinite block.

Warning

A single-replica application with maxUnavailable: 0 (or minAvailable: 1) tells the drain it may never evict the pod. The drain waits out the whole timeout and takes the pod regardless. A PDB cannot make one replica highly available. Run two.

Stateful and quorum applications#

For a quorum-based application such as etcd or a database with a raft group, size the PDB so a drain never breaks quorum: with three members, maxUnavailable: 1. Pair it with one-per-node placement so no single drain can reach two members at once. See .