Configuring Pod Affinity and Anti-Affinity
1. Using Pod Affinity
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels: { app: cache }
topologyKey: kubernetes.io/hostname
| Use | Example |
| Co-locate | App with cache on same node |
| Same zone | topologyKey: zone |
2. Using Pod Anti-Affinity
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector: { matchLabels: { app: web } }
topologyKey: kubernetes.io/hostname # one per node (HA)
| Use | Detail |
| HA | Spread replicas across nodes |
| Noisy neighbor | Avoid co-locating resource hogs |
3. Setting Topology Keys
| topologyKey | Scope |
kubernetes.io/hostname | Per-node |
topology.kubernetes.io/zone | Per-zone |
topology.kubernetes.io/region | Per-region |
4. Using requiredDuringScheduling
Warning: Required pod affinity is computationally expensive at scale (O(pods × nodes)). Prefer topology spread constraints.
5. Using preferredDuringScheduling
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector: { matchLabels: { app: web } }
topologyKey: kubernetes.io/hostname
6. Configuring Label Selectors
| Field | Use |
| matchLabels | Equality |
| matchExpressions | Set-based |
7. Setting Namespace Selectors
podAffinityTerm:
namespaceSelector: { matchLabels: { env: prod } }
labelSelector: { matchLabels: { app: web } }
topologyKey: kubernetes.io/hostname
| Field | Effect |
| namespaces | Explicit list |
| namespaceSelector | Match by namespace labels |
| Both omitted | Same namespace as pod |
8. Understanding Topology Domains
A topology domain = set of nodes sharing the same value for the topologyKey label.
| topologyKey | Domain count |
| hostname | = node count |
| zone | = AZ count |
9. Combining Affinity Rules
| Combination | Pattern |
| Cache co-location + replica HA | podAffinity to cache + podAntiAffinity to self |
| Zone redundancy | podAntiAffinity zone + topology spread |
10. Troubleshooting Pod Placement
| Symptom | Cause |
| FailedScheduling | Required (anti-)affinity unsatisfiable |
| Slow scheduling | Heavy required podAffinity rules |
| Cross-namespace miss | Forgot namespaceSelector |