Using pod Anti Affinity to force only 1 pod per node
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Pod anti-affinity is a Kubernetes scheduling constraint that prevents pods from being placed on the same node as other pods matching certain criteria. The most common use case is ensuring that only one instance of a particular pod runs per node — critical for stateful workloads, data-locality requirements, and high-availability deployments where co-located replicas would create a single point of failure.
Required vs Preferred Anti-Affinity
Kubernetes offers two types of anti-affinity:
| Type | Behavior | What happens if no node is available |
requiredDuringSchedulingIgnoredDuringExecution | Hard constraint — must be satisfied | Pod stays Pending |
preferredDuringSchedulingIgnoredDuringExecution | Soft constraint — best effort | Pod is scheduled on a shared node |
One Pod Per Node: Required Anti-Affinity
Key elements:
labelSelector: Matches pods withapp: my-service— the same label as this deployment's podstopologyKey: kubernetes.io/hostname: The anti-affinity applies per node (hostname). Each node is a separate topology domain- Effect: No two pods with
app: my-servicecan be scheduled on the same node
One Pod Per Node: Preferred Anti-Affinity
Use preferred anti-affinity when you want spreading but do not want pods stuck in Pending:
The weight (1-100) determines how strongly the scheduler prefers this constraint relative to other scheduling factors.
One Pod Per Zone
Spread pods across availability zones instead of nodes:
This ensures at most one pod per availability zone — useful for cross-zone redundancy.
Topology Spread Constraints (Alternative)
Kubernetes 1.19+ introduced topologySpreadConstraints as a more flexible alternative:
| Parameter | Meaning |
maxSkew: 1 | Maximum difference in pod count between any two nodes |
whenUnsatisfiable: DoNotSchedule | Hard constraint (like required anti-affinity) |
whenUnsatisfiable: ScheduleAnyway | Soft constraint (like preferred anti-affinity) |
topologySpreadConstraints is more powerful than anti-affinity for controlling distribution because it considers the overall balance, not just pairwise exclusion.
DaemonSet Alternative
If you truly need exactly one pod per node, a DaemonSet may be simpler:
A DaemonSet automatically schedules exactly one pod on every node (or a subset selected by nodeSelector/nodeAffinity). Use this when you want full coverage, not just uniqueness.
StatefulSet with Anti-Affinity
For stateful workloads with persistent volumes:
Verifying Anti-Affinity
Common Pitfalls
- More replicas than nodes: With required anti-affinity and 3 nodes but 5 replicas, 2 pods stay Pending forever. Use preferred anti-affinity or add more nodes.
- Wrong
topologyKey:kubernetes.io/hostnamemeans one pod per node. If you usetopology.kubernetes.io/zone, it means one pod per availability zone (not per node). Choose the right key for your spreading goal. - Label selector mismatch: The
labelSelectorin the anti-affinity rule must match the pod's own labels. If the labels do not match, the anti-affinity has no effect and pods are scheduled freely. IgnoredDuringExecutionmeans no eviction: If a node later gets a second matching pod (e.g., through manual scheduling), the first pod is not evicted. Anti-affinity only affects scheduling, not running pods.- Performance with many pods: Anti-affinity with large numbers of pods (hundreds) can slow down the scheduler because it must check all existing pods. Use
topologySpreadConstraintsfor better performance in large clusters.
Summary
- Use
podAntiAffinitywithrequiredDuringSchedulingIgnoredDuringExecutionto guarantee at most one pod per node - Set
topologyKey: kubernetes.io/hostnamefor per-node spreading - Use
preferredDuringSchedulingIgnoredDuringExecutionwhen you prefer spreading but cannot guarantee enough nodes - Consider
topologySpreadConstraints(Kubernetes 1.19+) for more flexible distribution control - Use a
DaemonSetif you need exactly one pod on every node, not just uniqueness - Ensure your cluster has at least as many nodes as replicas when using required anti-affinity
Related reading
- Validating helm chart content
- ValidationError missing required field selector in io.k8s.api.v1.DeploymentSpec
- View log files of crashed pods in kubernetes
- Volume is already exclusively attached to one node and can't be attached to another
- using read replication in mysql
- Using recurrence relations to prove a function has exponential runtime?
- VPN access for applications running inside a shared Kubernetes cluster
- Wait for kubernetes job to complete on either failure/success using command line

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.