Affinity & Anti-Affinity
Affinity rules express flexible preferences about which nodes or Pods to co-locate or avoid.
Affinity is a richer, more expressive version of nodeSelector. It comes in two flavors.
Node affinity
Chooses nodes by label, but with soft and hard rules:
requiredDuringSchedulingIgnoredDuringExecution— a hard rule; the Pod won't schedule without a match.preferredDuringSchedulingIgnoredDuringExecution— a soft preference the scheduler tries to honor.
Pod affinity & anti-affinity
These place Pods relative to other Pods:
- Pod affinity — schedule near Pods with a given label (e.g. keep a cache next to its app).
- Pod anti-affinity — schedule away from them (e.g. spread replicas across nodes for resilience).
Example
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
containers:
- name: nginx
image: nginx:1.27When to use it
- A team uses podAntiAffinity to spread Deployment replicas across availability zones so a single zone failure does not take down all pods.
- A latency-sensitive service uses podAffinity to co-locate its pods with the cache pods they query most frequently onto the same node.
- A platform team uses preferredDuringSchedulingIgnoredDuringExecution affinity so pods try to land on cost-optimal nodes but still schedule when they cannot.
More examples
Spread pods across zones with anti-affinity
Requires that no two web pods land in the same availability zone, distributing replicas for zone-failure resilience.
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: web
topologyKey: topology.kubernetes.io/zoneNode affinity by label
Requires the pod to be scheduled only on nodes labelled node-type=high-mem, enabling more expressive constraints than nodeSelector.
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values: [high-mem]Preferred co-location with cache
Tells the scheduler to prefer placing this pod on a node that already runs a redis-cache pod, reducing network latency.
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
podAffinityTerm:
labelSelector:
matchLabels:
app: redis-cache
topologyKey: kubernetes.io/hostname
Discussion