Spread Critical Pods with Anti-Affinity
Use pod anti-affinity or topology spread so replicas of a critical service never land on the same node or zone, surviving a single failure.
Task
Ensure replicas of a critical service are spread across failure domains.
When to use this
A deployment schedules all replicas onto one node or one zone, so a single node or zone failure takes the whole service down.
Prerequisites
- A multi-node or multi-zone cluster
- Node labels indicating the failure domain
Steps
1. Label nodes with their zone or failure domain.
Expected output: The scheduler can distinguish domains.
2. Add topologySpreadConstraints or preferred anti-affinity to the deployment.
Expected output: Replicas are spread across domains.
3. Balance the spread against scheduling feasibility with whenUnsatisfiable policy.
Expected output: Spreading does not leave pods Pending needlessly.
4. Verify placement after a rollout and after a node drain.
kubectl get pods -o wide -l app=webExpected output: Spreading holds under change.
Troubleshooting
Problem
Pods stuck Pending
Solution
Preferred or ScheduleAnyway avoids hard failures; reserve required anti-affinity for the most critical services only.
Problem
Spreading not effective
Solution
Ensure enough domains and that affinity terms match the actual node labels.
Limitations
- Strict anti-affinity can leave pods unschedulable in small clusters or during scale-down.
- It spreads replicas but does not guarantee capacity in every domain.
Context
Ensure replicas of a critical service are spread across failure domains. A deployment schedules all replicas onto one node or one zone, so a single node or zone failure takes the whole service down.
Steps
- Label nodes with their zone or failure domain. Expected: The scheduler can distinguish domains.
- Add topologySpreadConstraints or preferred anti-affinity to the deployment. Expected: Replicas are spread across domains.
- Balance the spread against scheduling feasibility with whenUnsatisfiable policy. Expected: Spreading does not leave pods Pending needlessly.
- Verify placement after a rollout and after a node drain. Expected: Spreading holds under change.
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector: { matchLabels: { app: web } }
Verify
- The scheduler can distinguish domains.
- Replicas are spread across domains.
- Spreading does not leave pods Pending needlessly.
- Spreading holds under change.
Limits
- Strict anti-affinity can leave pods unschedulable in small clusters or during scale-down.
- It spreads replicas but does not guarantee capacity in every domain.