Skip to main content
RunBook Academy

KubernetesXXIV · Pod Affinity and Anti-AffinityPod affinity

preferredDuringSchedulingIgnoredDuringExecution — soft inter-pod affinity

Advanced⏱ ~16 minkubectlkubeadm

What you'll learn

  • Configure preferredDuringSchedulingIgnoredDuringExecution for Pod affinity and anti-affinity
  • Reason about weight (1-100) and its effect on scoring
  • Distinguish preferred from required affinity in failure modes
  • Apply preferred affinity to common production patterns

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

Not yet marked complete on this device.

preferredDuringSchedulingIgnoredDuringExecution is the soft variant of Pod affinity and anti-affinity. Instead of eliminating nodes that don’t satisfy, it adds weight to the score. If no node satisfies the preference, the Pod still schedules. This lesson covers the syntax, the weight semantics, and when to use preferred vs required.

The syntax

spec:
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 80
        podAffinityTerm:
          topologyKey: kubernetes.io/hostname
          labelSelector:
            matchLabels:
              app: cache
flowchart LR
    A[Feasible nodes] --> B[Score phase]
    B --> C{Node has Pod<br/>matching selector?}
    C -->|yes| D["Score += weight"]
    C -->|no| E[Score unchanged]
    D --> F[Final score]
    E --> F

The weight

The weight (1-100) is added to the node’s score for nodes that satisfy the preference. A weight of 100 is a strong preference; a weight of 10 is weak.

flowchart TB
    A["Node X<br/>has cache Pod"] --> B["Score: 80"]
    A2["Node Y<br/>no cache Pod"] --> B2["Score: 0"]
    A3["Node Z<br/>has cache Pod"] --> B3["Score: 80"]
    A --> C[Other plugins]
    A2 --> C
    A3 --> C
    C --> D[Final score]

Pod anti-affinity preferred

spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          topologyKey: kubernetes.io/hostname
          labelSelector:
            matchLabels:
            app: web

The Pod prefers to land on a node without an app: web Pod. If no such node exists, the Pod schedules anywhere with a low score.

Preferred vs required

flowchart TB
    A{Affinity type} -->|required| B["If no match: Pending"]
    A -->|preferred| C["If no match: schedule anywhere"]
    C --> D["Match: score += weight"]
Use preferred when…Use required when…
Latency optimisationHard separation (must not co-locate)
Performance preferenceCompliance / correctness
Operational preferenceHardware constraints
Failure mode: schedule anywhereFailure mode: Pending Pod

Combining preferred and required

spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - topologyKey: kubernetes.io/hostname
        labelSelector:
          matchLabels:
            app: web
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          topologyKey: topology.kubernetes.io/zone
          labelSelector:
            matchLabels:
              app: web

The Pod must not co-locate with app: web on the same node (required). The Pod prefers a different zone from existing app: web Pods (preferred). The combination gives strict node separation and zone preference.

Production patterns

Pattern 1: prefer co-location with cache

affinity:
  podAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 80
      podAffinityTerm:
        topologyKey: kubernetes.io/hostname
        labelSelector:
          matchLabels:
            app: cache

The Pod prefers a node with cache. If no such node exists, the Pod schedules anywhere.

Pattern 2: prefer separation from web

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        topologyKey: kubernetes.io/hostname
        labelSelector:
          matchLabels:
            app: web

The Pod prefers to be on a node without app: web. If all nodes have web Pods, the Pod schedules anyway.

Pattern 3: combine multiple preferences

affinity:
  podAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 50
      podAffinityTerm:
        topologyKey: kubernetes.io/hostname
        labelSelector:
          matchLabels:
            app: cache
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        topologyKey: kubernetes.io/hostname
        labelSelector:
          matchLabels:
            app: db

Prefer cache co-location (weight 50); prefer separation from db (weight 100). The db separation is stronger.

Failure modes

Failure 1: weight too low

preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
  podAffinityTerm:
    topologyKey: kubernetes.io/hostname
    labelSelector:
      matchLabels:
        app: cache

A weight of 1 is rarely significant in the total score; the scheduler’s other plugins dominate. The preference is effectively no-op.

The fix: increase the weight (50-100 is meaningful).

Failure 2: preference unsatisfiable

A preference that matches no Pod is silent. The Pod schedules anywhere. The fix: verify the cluster’s labels and Pods.

Failure 3: required mixed with preferred

# WRONG: required belongs in requiredDuringScheduling
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
  podAffinityTerm:
    required: true   # not valid here
    topologyKey: kubernetes.io/hostname
    labelSelector:
      matchLabels:
        app: cache

The required field is for nodeSelectorTerms in required affinity. Preferred uses only weight and podAffinityTerm.

Quiz

Knowledge check · 4 questions

  1. Q1. What does preferredDuringSchedulingIgnoredDuringExecution do for Pod affinity?

  2. Q2. Preferred Pod affinity is rare in production; required is the standard.

  3. Q3. Your team has a web Pod with preferred affinity for cache co-location (weight 80) and preferred anti-affinity for separation from other web Pods (weight 100). The Pod lands on a node without cache. Diagnose.

    Web Pod with preferred affinity for app cache weight 80 and preferred anti-affinity for app web weight 100. Cluster has nodes with cache and web Pods mixed.

  4. Q4. How does preferred Pod affinity interact with required Pod affinity in a single Pod spec?

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • Use preferred for operational placement. Latency, performance, cost — anything that prefers but allows fallback.
  • Use required for hard separation. A primary and replica that must not co-locate; a workload that must not share a node with another workload.
  • Verify weights. A weight of 50-100 is meaningful; a weight of 1 is not.
  • Combine preferred and required. A workload can have both: required for separation, preferred for performance.
  • Audit the resulting distribution. A dashboard that surfaces per-node Pod counts catches preference failures.

Preferred Pod affinity is the right tool for soft placement. Operators who use it deliberately have workloads that land predictably with sensible fallbacks.