A PodDisruptionBudget (PDB) doesn’t actually "maintain" availability; it limits the maximum number of pods that can be unavailable during voluntary disruptions.

Let’s see it in action. Imagine you have a critical frontend deployment with 3 replicas, and you want to ensure at least 2 are always available when you’re doing maintenance like draining a node.

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

Here, minAvailable: 2 is the crucial part. If you try to kubectl drain node-xyz, Kubernetes will look at this PDB. It sees that you’re about to evict a frontend pod. With 3 pods running, evicting one would leave only 2. Since minAvailable is 2, this is allowed. However, if you try to drain another frontend pod from a different node (or the same node if it could tolerate it), Kubernetes would see that evicting another pod would bring the count down to 1, violating the minAvailable: 2 constraint. The drain operation for that specific pod would be blocked until one of the other frontend pods becomes available again.

This mechanism is essential for preventing accidental downtime during cluster operations. When you perform voluntary disruptions like node drains, rolling updates (where pods are deleted and recreated), or cluster upgrades, Kubernetes respects PDBs. If an operation would violate a PDB, the operation on that specific pod is delayed. It’s not that the operation stops entirely, but rather that the eviction of that particular pod is "cordoned" until the condition is met.

The selector is how the PDB identifies which pods it applies to. It uses the same label selector syntax as Services and Deployments. In our example, it targets all pods with the label app: frontend. This allows you to define PDBs for specific applications or tiers within your cluster. You could have a PDB for your databases, another for your API servers, and a different one for your frontend, each with its own availability guarantees.

You can also use maxUnavailable instead of minAvailable. If you have a deployment with 5 replicas and set maxUnavailable: 1, it means at most 1 pod can be unavailable during voluntary disruptions. This is equivalent to setting minAvailable: 4 for a 5-replica deployment. The choice between minAvailable and maxUnavailable often comes down to how you prefer to think about availability – do you focus on the minimum you must have, or the maximum you can afford to lose?

The key distinction is that PDBs only apply to voluntary disruptions. They do not protect against involuntary disruptions like node failures, hardware issues, or accidental deletion of pods. If a node crashes, the pods on it become unavailable, and the PDB won’t prevent this. It’s designed to give you control over planned maintenance and upgrades.

A common pitfall is misconfiguring the selector. If your PDB’s selector doesn’t match the labels on your application’s pods, the PDB will have no effect. Always double-check that kubectl get pods --show-labels shows the labels specified in your PDB’s selector on the target pods.

Another point of confusion is when you have multiple PDBs targeting the same set of pods. In such cases, the most restrictive PDB takes precedence. If one PDB requires minAvailable: 3 and another requires minAvailable: 2 for the same group of pods, Kubernetes will enforce minAvailable: 2 because it’s the tighter constraint.

The interaction with kubectl drain is where PDBs are most visible. When draining a node, kubectl drain attempts to evict all pods from that node. For each pod it tries to evict, it checks if doing so would violate any PDBs. If a violation would occur, the eviction is skipped, and kubectl drain will report that the pod is "protected" by a PDB. You can force the drain to proceed by adding the --force flag, but this bypasses the PDB protection and can lead to downtime.

When setting up PDBs, consider the total number of replicas for your application. If a deployment has only one replica, and you set minAvailable: 1, you cannot perform any voluntary disruptions on that pod without violating the PDB. In such scenarios, you might need to temporarily scale up your deployment before performing maintenance, or accept that the PDB will block operations.

The next concept you’ll run into is how PDBs interact with controllers like Deployments during rolling updates.

Want structured learning?

Take the full Kubernetes course →