# PodDisruptionBudget

> PodDisruptionBudgets cap voluntary evictions, and the number to watch is disruptionsAllowed: at 0, node drains, upgrades, and autoscaler scale-downs all stall. ZopNight captures minAvailable, maxUnavailable, healthy-pod counts, and the selector for matching budgets to workloads, and deletes-then-recreates PDBs around scheduled namespace downtime so a strict budget cannot block the stop.

Source: https://zop.dev/integrations/kubernetes/pdb
Updated: 2026-08-19

---

A PodDisruptionBudget limits how many of a workload's pods can be evicted voluntarily at once: during node drains, upgrades, and autoscaler consolidation. Set well, it keeps maintenance from taking a service down. Set badly, it makes maintenance impossible, and pins the nodes it blocks.

## disruptionsAllowed: the number that blocks a drain

The controller continuously computes `disruptionsAllowed` from the budget and current pod health, and discovery records it alongside `currentHealthy`, `desiredHealthy`, and `expectedPods`. When it reads 0, every eviction request is refused: `kubectl drain` hangs, managed node-pool upgrades stall, and the cluster autoscaler cannot remove the node, which means an under-packed machine keeps billing because a budget said so. A PDB stuck at 0 allowed disruptions is therefore a cost finding as much as an operational one.

## The configurations that get stuck

Two shapes produce permanent blockage. A `maxUnavailable` of 0 forbids all voluntary eviction outright. A `minAvailable` equal to (or above) the workload's replica count does the same thing arithmetically. That is common when someone sets `minAvailable: 2` on a 2-replica Deployment, or protects a single-replica workload at all. Both fields are captured verbatim, whichever the budget uses, so the stuck shapes are searchable across every cluster.

## Selector capture and workload matching

Each PDB's pod selector is recorded because coverage is evaluated by matching it against workload selectors in the same namespace. That is how "which workloads does any budget protect" and its inverse, workloads with no disruption protection at all, get answered from inventory alone.

```bash
kubectl get pdb -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,MIN:.spec.minAvailable,MAX-UNAVAIL:.spec.maxUnavailable,ALLOWED:.status.disruptionsAllowed
```

## Out of the way during scheduled stops

A strict budget would also block ZopNight's own scale-downs, so the namespace schedule handles PDBs the same way it handles HPAs: their specs are noted, the objects are deleted for the downtime window, and they are recreated exactly as they were at resume. The protection is intact all through working hours and simply absent while the environment is deliberately off.
