PodDisruptionBudget
Does ZopNight manage 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, for scheduled namespace downtime, removes and later recreates each PDB matched to a workload by its app label.
Rules that fire on PodDisruptionBudget
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.
kubectl get pdb -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,MIN:.spec.minAvailable,MAX-UNAVAIL:.spec.maxUnavailable,ALLOWED:.status.disruptionsAllowedOut of the way during scheduled stops
The namespace schedule also clears budgets as housekeeping, since scaling to zero is not an eviction and a PDB would not block it, but selectively: a PDB whose selector names a workload through its app or app.kubernetes.io/name label (the first such PDB per workload) is saved, deleted for the downtime window, and recreated exactly as it was at resume. Any other PDB is left in place and logged for manual cleanup. The protection is intact all through working hours and simply absent while the environment is deliberately off.