KubernetesXXIV · Pod Affinity and Anti-AffinityPod affinity
requiredDuringSchedulingRequiredDuringExecution — hard inter-pod affinity
What you'll learn
- Describe the difference between RequiredDuringExecution and IgnoredDuringExecution
- Configure requiredDuringSchedulingRequiredDuringExecution for hard inter-pod affinity
- Reason about eviction when the topology changes
- Identify the limited production use cases for this strict variant
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
requiredDuringSchedulingRequiredDuringExecution is the
strict variant of Pod affinity: the constraint must be
satisfied at scheduling time AND must continue to be
satisfied at execution time. If the topology changes (a
node’s labels are altered, a Pod is deleted), the Pod is
evicted. This lesson covers the strict variant, when it is
correct, and why it is rare in production.
The strict variant
spec:
affinity:
podAffinity:
requiredDuringSchedulingRequiredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: cache
The Pod must land on a node hosting app: cache AND must
continue to be on such a node. If the cache Pod is deleted
or moved, the dependent Pod is evicted.
flowchart TB
A["Pod scheduled with<br/>RequiredDuringExecution"] --> B[Pod runs on node with cache]
B --> C{Cache Pod deleted?}
C -->|yes| D[Pod evicted]
C -->|no| E[Pod continues]
Compared to the standard variant
| Aspect | IgnoredDuringExecution | RequiredDuringExecution |
|---|---|---|
| Scheduling | Required | Required |
| Runtime | Ignored | Required |
| Eviction on topology change | No | Yes |
The standard variant
(requiredDuringSchedulingIgnoredDuringExecution) is the
common one. The strict variant
(requiredDuringSchedulingRequiredDuringExecution) is
rare.
When the strict variant is correct
The strict variant is correct when the workload’s correctness depends on the relationship continuing. The canonical example: a sidecar that depends on a primary container running on the same node.
flowchart LR
A["Primary Pod<br/>app: db-primary"] -->|on node-01| B["Sidecar Pod<br/>app: db-replica"]
A -.->|if Primary deleted| C[Sidecar evicted]
C -.->|on another node| D["Wrong: sidecar without primary"]
If the primary Pod is deleted, the replica sidecar is evicted. The replica cannot run without the primary.
Other cases:
- Local cache that is not replicated. If the cache Pod is deleted, the dependent Pod must be evicted because there is no cache to read from.
- Local agent that depends on the workload. A logging sidecar that requires the main container to be running.
When the strict variant is wrong
The strict variant is wrong when the relationship is operational, not correctness-critical:
flowchart TB
A[Wrong cases] --> B[Latency optimisation]
A --> C[Performance preference]
A --> D[Cost preference]
B --> E["Use preferred<br/>instead"]
C --> E
D --> E
- Latency optimisation. Co-locate for low latency; but the workload works without co-location. Use preferred.
- Performance preference. “Prefer to be near X”; if X moves, the workload follows via re-scheduling, not eviction. Use preferred.
- Cost preference. “Prefer to be near X for free traffic”; if X moves, the cost changes but the workload works. Use preferred.
Eviction semantics
When the topology changes, the scheduler evicts the
dependent Pod. The eviction follows the Pod’s
terminationGracePeriodSeconds and respects any
PodDisruptionBudget.
sequenceDiagram
participant Cache as cache Pod
participant Web as web Pod (RequiredDuringExecution)
participant S as Scheduler
participant K as Kubelet
Note over Cache,Web: Both on node-01
S->>Cache: observe delete
S->>Web: evict (RequiredDuringExecution violated)
K->>Web: SIGTERM
Web->>K: terminate
Note over Web: web Pod re-scheduled<br/>or stays Pending
The eviction is automatic; the operator sees a Failed
event on the Pod with the reason Affinity not satisfied.
The performance cost
The strict variant requires the scheduler to monitor the topology continuously. Every Pod’s selector evaluation is repeated whenever any Pod’s labels change. For a cluster with thousands of Pods and tight selectors, this is expensive.
The cost is similar to the standard variant at scheduling time, but the runtime monitoring adds overhead. The scheduler’s “resync” interval controls how often the runtime evaluation runs.
Production patterns
Pattern 1: primary-replica with strict affinity
# Replica sidecar
spec:
affinity:
podAffinity:
requiredDuringSchedulingRequiredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: db-primary
containers:
- name: db-replica
image: db:v1
The replica is evicted if the primary moves. The replica must always have a primary on the same node.
Pattern 2: cache with no replication
# Workload that requires the cache
spec:
affinity:
podAffinity:
requiredDuringSchedulingRequiredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: cache-local
containers:
- name: web
image: web:v1
The web Pod is evicted if the local cache is deleted. The web Pod requires the cache; without it, the Pod is broken.
Anti-patterns
Anti-pattern 1: using strict variant as default
# WRONG: standard variant is the default
affinity:
podAffinity:
requiredDuringSchedulingRequiredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: cache
The standard variant (IgnoredDuringExecution) is the
default for a reason. Most co-location is operational,
not correctness-critical. Use the strict variant only when
the relationship is required.
Anti-pattern 2: strict variant with broad selector
labelSelector:
matchLabels:
app: web # matches many Pods
A selector that matches many Pods requires continuous monitoring of many Pods. Performance degrades.
Anti-pattern 3: strict variant with PDB violation
A Pod with RequiredDuringExecution and a PodDisruptionBudget
(maxUnavailable: 0) can violate the PDB when evicted.
The scheduler evicts the Pod; the PDB prevents it;
the Pod is stuck.
The fix: relax the PDB to allow the eviction, or use the standard variant.
Quiz
Knowledge check · 4 questions
Q1. What does requiredDuringSchedulingRequiredDuringExecution do?
Q2. The standard Pod affinity (requiredDuringSchedulingIgnoredDuringExecution) evicts Pods when the topology changes.
Q3. Your team's primary-replica database uses requiredDuringSchedulingRequiredDuringExecution to keep the replica on the same node as the primary. The primary Pod is deleted; the replica is evicted. Diagnose.
Replica Pod uses requiredDuringSchedulingRequiredDuringExecution with labelSelector app db-primary. The primary Pod is deleted; the replica is evicted.
Q4. When is the strict variant of Pod affinity (requiredDuringSchedulingRequiredDuringExecution) correct?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Default to
IgnoredDuringExecution. The standard variant is correct for most use cases. - Use
RequiredDuringExecutionfor hard correctness. A sidecar that cannot run without its primary is a candidate. - Combine with PodDisruptionBudget deliberately. A strict Pod may violate a PDB; the discipline is to align the two.
- Monitor eviction events. A Pod evicted for “Affinity not satisfied” is a signal that the relationship broke; the operator investigates.
- Audit strict-variant usage. A query for Pods with
requiredDuringSchedulingRequiredDuringExecutionflags candidates for review.
The strict variant of Pod affinity is a sharp tool. Use it when the relationship is hard; reach for the standard variant otherwise.