DevOps Dictionary

Kubernetes Pod Affinity and Anti-Affinity

Kubernetes Pod Affinity and Anti-Affinity are scheduling rules that tell Kubernetes where to place pods based on the labels of other pods already running in the cluster. Pod affinity places pods near each other, while pod anti-affinity keeps pods apart. In practical terms, they help you control workload placement for latency, availability, cost, and operational safety.

What it does

By default, the Kubernetes scheduler places pods on nodes that have enough available resources and satisfy basic constraints. Pod affinity and anti-affinity add another layer of intent: they let you say, “run this pod close to those pods” or “do not run this pod near those pods.”

  • Pod affinity places pods together based on matching labels and a topology domain.
  • Pod anti-affinity spreads pods apart based on matching labels and a topology domain.
  • Topology domains define what “together” or “apart” means, such as the same node, availability zone, region, or custom failure domain.

These rules are useful when Kubernetes resource requests alone are not enough to express how your workloads should be placed.

How it works

Pod affinity and anti-affinity are configured in a pod spec under spec.affinity. The scheduler evaluates these rules during pod placement.

The rules usually depend on three parts:

  • Label selectors: Match other pods by labels, such as app=redis or tier=frontend.
  • Topology key: Defines the placement boundary, such as kubernetes.io/hostname for a node or topology.kubernetes.io/zone for an availability zone.
  • Rule strength: Defines whether the scheduler must follow the rule or should try to follow it.

Required rules

requiredDuringSchedulingIgnoredDuringExecution means the scheduler must satisfy the rule when placing the pod. If no valid node exists, the pod stays pending.

This is useful for hard requirements, such as keeping replicas of the same critical service on different nodes.

Preferred rules

preferredDuringSchedulingIgnoredDuringExecution means the scheduler tries to satisfy the rule, but it can still place the pod elsewhere if needed.

This is safer for many production workloads because it reduces the chance of pods getting stuck during node pressure, upgrades, or scaling events.

Common use cases

  • Keep replicas apart: Use pod anti-affinity to avoid running all replicas of a service on the same node or zone.
  • Place related services together: Use pod affinity to place an application close to its cache, queue worker, or sidecar-like supporting workload.
  • Improve availability: Spread critical workloads across nodes, racks, zones, or custom failure domains.
  • Reduce latency: Place chatty services in the same zone when network latency matters.
  • Control noisy neighbors: Keep CPU-heavy or I/O-heavy workloads away from each other using labels and anti-affinity.

For example, if you run Apache Airflow on EKS, you may want schedulers, workers, and supporting services placed with different rules depending on their failure tolerance and traffic patterns. A guide like deploying Apache Airflow on AWS Elastic Kubernetes Service shows the kind of real workload where placement decisions can matter.

Simple example

This example uses pod anti-affinity to prefer placing replicas of the same app on different nodes:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchLabels:
                    app: api
                topologyKey: kubernetes.io/hostname
      containers:
        - name: api
          image: example/api:1.0.0

With this configuration, Kubernetes tries to avoid placing multiple app=api pods on the same node. If the cluster has fewer available nodes than replicas, the scheduler can still place more than one replica on a node because the rule is preferred, not required.

Affinity vs anti-affinity

  • Use pod affinity when pods should run near matching pods. Example: place an app pod in the same zone as a cache pod.
  • Use pod anti-affinity when pods should avoid matching pods. Example: spread replicas of the same deployment across different nodes.

The key question is whether proximity helps or hurts the workload. If being close improves latency or reduces data transfer, affinity may help. If being together increases outage risk, anti-affinity is usually the better fit.

Pod affinity vs node affinity

Pod affinity and node affinity solve different scheduling problems.

  • Pod affinity and anti-affinity make decisions based on other pods and their labels.
  • Node affinity makes decisions based on node labels, such as instance type, disk type, region, or GPU availability.

Use node affinity when the workload needs a specific kind of node. Use pod affinity or anti-affinity when the workload needs to be placed relative to other pods.

Pod anti-affinity vs topology spread constraints

Pod anti-affinity and topology spread constraints can both spread pods, but they work differently.

  • Pod anti-affinity expresses “do not place this pod near matching pods.”
  • Topology spread constraints express “keep matching pods evenly distributed across topology domains.”

For many modern Kubernetes clusters, topology spread constraints are easier to use for even replica distribution. Pod anti-affinity is still useful when you need stricter separation logic based on pod labels.

Benefits

  • Better availability: Anti-affinity can reduce the blast radius of a node or zone failure.
  • More control: Teams can encode placement requirements directly in Kubernetes manifests.
  • Workload-aware scheduling: The scheduler can account for relationships between services, not only CPU and memory.
  • Useful for stateful systems: Databases, brokers, and quorum-based systems often need replicas placed apart.

Tradeoffs and limitations

  • Hard rules can block scheduling: Required affinity or anti-affinity can leave pods pending if the cluster cannot satisfy the rule.
  • Rules can increase scheduling complexity: Large clusters with many inter-pod rules may add scheduler work.
  • Labels must be reliable: Incorrect or inconsistent labels can cause unexpected placement.
  • Rules apply during scheduling: The IgnoredDuringExecution behavior means Kubernetes does not evict running pods if labels or topology change later.
  • Over-constraining hurts autoscaling: Strict placement rules can make cluster autoscaler behavior harder to predict.

During Kubernetes upgrades, strict anti-affinity can also affect how quickly workloads reschedule when nodes are drained. If you manage production clusters, review placement rules as part of your upgrade planning. These practical tips for Kubernetes upgrades cover related operational concerns.

Using it in infrastructure workflows

Pod affinity and anti-affinity rules often live in Helm charts, Kustomize overlays, Terraform-managed manifests, or GitOps repositories. If your team manages Kubernetes resources through Terraform, you can define these rules alongside deployments, services, and config maps. See this guide on how to deploy Kubernetes resources using Terraform for a related workflow.

Teams that manage cloud resources through Kubernetes APIs may also combine scheduling rules with platform tools such as Crossplane. For example, you might provision cloud infrastructure and deploy workloads through Kubernetes-native definitions, as shown in this guide to deploy AWS resources using Crossplane on Kubernetes.

Practical guidance

  • Prefer preferredDuringSchedulingIgnoredDuringExecution unless you have a strict availability or compliance requirement.
  • Use topology.kubernetes.io/zone when you care about zone-level failure separation.
  • Use kubernetes.io/hostname when you care about node-level separation.
  • Keep labels simple and consistent, such as app, component, tier, and release.
  • Test scheduling behavior in a staging cluster before applying strict rules to production workloads.
  • Monitor pending pods after rollout. A pending pod with scheduler events about affinity rules usually means the cluster has no valid placement option.

In short

Kubernetes Pod Affinity and Anti-Affinity give you label-based control over where pods run relative to other pods. Use affinity to place related workloads close together. Use anti-affinity to spread replicas or conflicting workloads apart. Start with preferred rules, choose the right topology key, and avoid hard constraints unless your workload truly needs them.

A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
Y
X
Z