Home/Learn/Kubernetes/Production Patterns — Probes, Affinity & Pod Disruption

Production Patterns — Probes, Affinity & Pod Disruption

Advanced
Production

Production Kubernetes requires readiness/liveness/startup probes, pod affinity and anti-affinity rules for HA placement, Pod Disruption Budgets for safe maintenance, and resource quotas for cluster stability.

Overview

Running Kubernetes in production goes beyond basic Deployments. Probes (readiness, liveness, startup) ensure traffic only goes to healthy pods and stuck pods are restarted automatically. Pod anti-affinity spreads replicas across availability zones — preventing all pods from being on one node that fails. Pod Disruption Budgets (PDB) limit how many pods can be unavailable during a maintenance drain, protecting your SLA. Resource requests/limits prevent noisy-neighbour problems and enable the scheduler to make optimal placement decisions.

Probe Deep Dive

Three probe types work together: startup (gives slow-starting apps time), readiness (controls traffic routing), and liveness (triggers pod restart). Using wrong probe types or thresholds causes cascading failures.

Kubernetes probe configuration and anti-patterns
spec:

  containers:

    - name: app

      image: my-app:v1.2.3



      # startupProbe: gives slow-starting containers time to init

      # Checked every periodSeconds, up to failureThreshold times

      # Total grace: 30s * 10 = 5 minutes max startup time

      # ONLY checked during startup; disables liveness until it succeeds

      startupProbe:

        httpGet:

          path: /health/startup   # a fast endpoint that returns 200 when ready to start

          port: 8080

        failureThreshold: 30      # 30 * 10s = 5 minutes max

        periodSeconds: 10



      # readinessProbe: controls TRAFFIC routing (not restart)

      # If failing: removed from Service endpoints (no traffic)

      # If passing: added to Service endpoints (gets traffic)

      # ⚠️ Use for: dependency checks (DB connected?), circuit breaker open?

      readinessProbe:

        httpGet:

          path: /health/ready

          port: 8080

        initialDelaySeconds: 0     # startupProbe covers startup

        periodSeconds: 10

        failureThreshold: 3        # 3 failures = removed from endpoints

        successThreshold: 1        # 1 success = back in rotation



      # livenessProbe: triggers RESTART if failing

      # ⚠️ Be conservative — aggressive liveness = restart loops under load

      # Should ONLY fail if the process is genuinely stuck

      livenessProbe:

        httpGet:

          path: /health/live

          port: 8080

        periodSeconds: 15

        failureThreshold: 3        # 45 seconds to trigger restart

        timeoutSeconds: 5



# Common mistake: liveness probe checking DB connectivity

# If DB is down, liveness restarts ALL pods → more load on recovering DB → cascade failure

# Readiness: check DB (remove from traffic)

# Liveness:  only check if process is stuck (not external deps)

Pod Anti-Affinity — Spread Across Zones

Pod anti-affinity rules ensure replicas spread across nodes and availability zones, preventing a single node/zone failure from taking down all pods.

Pod anti-affinity and topology spread constraints
spec:

  template:

    spec:

      # Prefer spreading pods across zones (soft rule — best effort)

      affinity:

        podAntiAffinity:

          preferredDuringSchedulingIgnoredDuringExecution:

            - weight: 100

              podAffinityTerm:

                labelSelector:

                  matchLabels:

                    app: my-app

                topologyKey: topology.kubernetes.io/zone   # spread across AZs

          # Hard rule (never schedule 2 pods on same node):

          requiredDuringSchedulingIgnoredDuringExecution:

            - labelSelector:

                matchLabels:

                  app: my-app

              topologyKey: kubernetes.io/hostname           # unique per node



      # topologySpreadConstraints (modern, more powerful alternative)

      topologySpreadConstraints:

        - maxSkew: 1                         # max 1 pod difference between zones

          topologyKey: topology.kubernetes.io/zone

          whenUnsatisfiable: DoNotSchedule   # hard (ScheduleAnyway = soft)

          labelSelector:

            matchLabels:

              app: my-app

        - maxSkew: 1

          topologyKey: kubernetes.io/hostname

          whenUnsatisfiable: ScheduleAnyway  # prefer, but don't block

          labelSelector:

            matchLabels:

              app: my-app



# Result: 6 pods across 3 zones = 2 pods per zone

# Zone failure: only 2/6 pods lost (traffic served by remaining 4)

Pod Disruption Budget (PDB)

PDBs protect your SLA during voluntary disruptions (node drain for maintenance, cluster upgrades). They tell Kubernetes how many pods must remain available at all times.

PodDisruptionBudget — protect SLA during maintenance
# PodDisruptionBudget — protect SLA during maintenance

apiVersion: policy/v1

kind: PodDisruptionBudget

metadata:

  name: my-app-pdb

spec:

  # minAvailable: minimum pods that MUST be available

  minAvailable: 2          # always keep at least 2 pods running



  # OR: maxUnavailable: maximum pods that CAN be unavailable

  # maxUnavailable: 1      # at most 1 pod can be down at a time



  selector:

    matchLabels:

      app: my-app



# Effect: kubectl drain node-1 will wait/fail if draining would

# violate the PDB (i.e., would reduce available pods below minAvailable)



# Node drain respects PDBs:

kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data

# Evicting pod my-app-7f9c8d-abc12...

# eviction.policy/v1 PodDisruptionBudget: Cannot evict pod as it would

# violate the pod's disruption budget. ← PDB protected the pod



# For 3 replicas:

# minAvailable: 2 → at most 1 can be evicted at a time

# minAvailable: 1 → 2 can be evicted (risky)

# maxUnavailable: 0 → zero downtime maintenance (slowest drain)

# maxUnavailable: 1 → one pod at a time (most common)



# Check PDB status

kubectl get pdb

# NAME         MIN AVAILABLE  MAX UNAVAILABLE  ALLOWED DISRUPTIONS  AGE

# my-app-pdb   2              N/A              1                    5d

Key Points to Remember

  • 1startupProbe gives slow apps time to initialise without triggering liveness restarts.
  • 2readinessProbe removes pods from Service endpoints — use for dependency health, not liveness.
  • 3livenessProbe should only restart the pod if the process is genuinely stuck — not for DB down.
  • 4Pod anti-affinity + topologySpreadConstraints spread pods across nodes and AZs for HA.
  • 5PDBs prevent cluster maintenance from taking your service below its availability SLA.
  • 6Aggressive liveness probes under load cause restart loops — set failureThreshold conservatively.

Interview Questions

Sign in to ask Aria
1

What is the difference between readinessProbe and livenessProbe in terms of consequence?

2

How do you ensure a Kubernetes service survives a node failure in production?

Ask Aria about Production Patterns — Probes, Affinity & Pod Disruption

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…