Skip to main content

More Info:

Advisory: define a PodDisruptionBudget for each multi-replica Deployment so node drains and rollouts keep a minimum number of pods available.

Risk Level

Informational

Address

Security

Compliance Standards

  • Cloudanix Best Practice

Triage and Remediation

Remediation

Manual Steps

  1. List all multi-replica Deployments and their selectors
    • Run on: any machine with kubectl access
    • Command:
    • Review: Identify which multi-replica Deployments are critical (user-facing, stateful backends, control-plane add-ons, etc.).
  2. List existing PodDisruptionBudgets and their selectors
    • Run on: any machine with kubectl access
    • Command:
    • Review: For each PDB, note .metadata.namespace, .metadata.name, .spec.selector.matchLabels, and either .spec.minAvailable or .spec.maxUnavailable.
  3. Map Deployments to PDBs and find gaps
    • For each multi-replica Deployment from step 1, check if there is a PDB in the same namespace whose spec.selector.matchLabels matches the Deployment’s spec.selector.matchLabels.
    • If no matching PDB exists, or the PDB selector is broader/narrower than intended, mark that Deployment as needing a new or corrected PDB.
  4. Design an appropriate availability policy per Deployment
    • For each marked Deployment, decide:
      • Whether to use minAvailable (e.g., "80%" or replicas-1) to guarantee a minimum number of pods, or
      • maxUnavailable (e.g., 1) to allow controlled disruptions.
    • Ensure the chosen value is compatible with the Deployment’s spec.replicas (e.g., do not set minAvailable equal to replicas if you still need to allow voluntary disruptions such as node drains).
  5. Create or adjust PodDisruptionBudgets
    • Run on: any machine with kubectl access
    • For a missing PDB, create a manifest like:
    • Apply it:
    • For an existing but misconfigured PDB, edit and correct it:
      Adjust spec.selector.matchLabels to match the Deployment labels and tune minAvailable/maxUnavailable per step 4.
  6. Verify PDB coverage for all multi-replica Deployments
    • Run on: any machine with kubectl access
    • Command to re-check multi-replica Deployments:
    • For each listed Deployment, confirm there is at least one PDB in the same namespace whose spec.selector.matchLabels matches the Deployment’s selector:
    • Optionally, simulate a drain to ensure PDBs are enforced (non-disruptively on a test node/pool):
  • Focus review on Deployments where REPLICAS is 2 or more (single-replica workloads do not benefit from a PDB for disruption tolerance).
Key columns to review:
  • NAMESPACE, NAME: where the PDB lives.
  • MIN AVAILABLE / MAX UNAVAILABLE: ensures enough pods stay up.
  • SELECTOR: which pods the PDB matches.
A problem is indicated when:
  • A namespace has multi-replica Deployments but no PDBs at all, or
  • There are PDBs, but their SELECTOR labels do not correspond to any multi-replica Deployment’s pod labels.
A problem is indicated when, for a multi-replica Deployment:
  • There is no PDB in the same namespace whose selector matchLabels would match that Deployment’s pod labels, or
  • The PDB exists but its MIN AVAILABLE / MAX UNAVAILABLE values are clearly inconsistent with the desired availability for that workload (this judgment must be made by a human).
A problem is indicated when:
  • The Deployment’s spec.selector.matchLabels do not line up with any PDB spec.selector.matchLabels, meaning a node drain or rollout could evict all pods, or
  • No PDB exists at all for an application that you consider critical and that runs with multiple replicas.
Explanation of output (what indicates a problem):
  • Lines starting with MISSING_PDB:
    • Example: MISSING_PDB my-namespace web-frontend 3 selector=app=web,role=frontend
    • Interpretation: this Deployment has replicas >= 2 and no PodDisruptionBudget with a matching label selector was found in its namespace. This is a candidate that should have a PodDisruptionBudget defined and reviewed.
  • Lines starting with WARN:
    • Example: WARN my-namespace legacy-app 4 NO matchLabels in selector (review manually)
    • Interpretation: the Deployment’s .spec.selector.matchLabels is empty; automatic matching to a PDB is not reliable. Manually inspect this Deployment and any PDBs in the same namespace.
  • Lines starting with OK:
    • Example: OK my-namespace api-server 5 selector=app=api PDBs=1
    • Interpretation: at least one PodDisruptionBudget exists whose selector exactly matches the Deployment’s matchLabels. These look compliant but still deserve human review for correct minAvailable/maxUnavailable values.