How to Configure Kubernetes Topology Spread Constraints
In this tutorial, you'll learn about How to Configure Kubernetes Topology Spread Constraints. We cover key concepts, practical examples, and best practices.
The Problem
Your pods are concentrated in one availability zone despite using topology spread constraints. When that zone fails, the entire application goes down. The spread constraints either do not distribute pods or prevent scheduling entirely.
Quick Fix
Fix 1: Basic Topology Spread Constraint
WRONG — no spread constraints:
spec:
replicas: 6
template:
spec:
# no topologySpreadConstraints — pods may all go to one zone
RIGHT — spread across zones:
spec:
replicas: 6
template:
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: my-app
This ensures no more than 1 pod difference between zones. With 6 replicas and 3 zones: 2 per zone.
Fix 2: maxSkew Misconfiguration
WRONG — maxSkew too restrictive:
maxSkew: 1
whenUnsatisfiable: DoNotSchedule
# With 3 zones and 4 replicas: can schedule 2+1+1 (max difference is 1, OK)
# With 3 zones and 1 replica: 1+0+0 (max difference is 1, OK)
RIGHT — choose maxSkew based on your tolerance:
# maxSkew: 1 — strictest, allows at most 1 pod difference
# maxSkew: 2 — allows up to 2 pod difference (more flexible)
Fix 3: whenUnsatisfiable Behavior
WRONG — using DoNotSchedule for bursting scenarios:
whenUnsatisfiable: DoNotSchedule
# (during scale-up, pods stay Pending if no zone meets the skew requirement)
RIGHT — use ScheduleAnyway for flexible spreading:
topologySpreadConstraints:
- maxSkew: 2
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: my-app
With ScheduleAnyway, the scheduler does its best but does not block scheduling if constraints cannot be met.
Fix 4: Multiple Topology Keys
Spread across zones first, then hosts:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: my-app
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: my-app
Fix 5: Node Label Selector
WRONG — applying constraints to nodes that do not have the topology label:
kubectl get nodes --show-labels | grep topology.kubernetes.io/zone
# (if no zones are labeled, the constraint has no effect)
RIGHT — label nodes with zones:
kubectl label node worker-1 topology.kubernetes.io/zone=us-east-1a
kubectl label node worker-2 topology.kubernetes.io/zone=us-east-1b
kubectl label node worker-3 topology.kubernetes.io/zone=us-east-1c
Fix 6: Check Skew Violations
kubectl describe pod my-app-xyz
# Events:
# Type Reason Age From Message
# Warning TopologySpread 10s default-scheduler Found 3 matching pods, max skew is 2
kubectl get pods -o wide --selector=app=my-app
# NAME READY NODE
# my-app-1 Running worker-1 (us-east-1a)
# my-app-2 Running worker-1 (us-east-1a) ← skew violation
# my-app-3 Running worker-2 (us-east-1b)
Use DodaTech's Topology Visualizer to see pod distribution across zones and nodes, and simulate constraint changes before applying them.
Prevention
- Label nodes with zone/region topology keys.
- Use
DoNotSchedulefor production-critical spreading. - Use
ScheduleAnywayfor development or burstable workloads. - Set
nodeAffinityto restrict constraint evaluation to specific nodes. - Monitor
kube-schedulermetrics for constraint violations.
Common Mistakes with topology spread
- Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
These mistakes appear frequently in real-world K8S code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro