Skip to main content
RunBook Academy

KubernetesXXIII · nodeSelector and Node AffinityNode affinity

preferredDuringSchedulingIgnoredDuringExecution — soft node affinity

Advanced⏱ ~16 minkubectlkubeadm

What you'll learn

  • Configure preferredDuringSchedulingIgnoredDuringExecution node affinity
  • Reason about the 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-constraint variant of Node Affinity. Instead of eliminating nodes that don’t match, it adds weight to the score. If no node matches the preference, the Pod still schedules on any feasible node. This lesson covers the syntax, the weight semantics, and when to reach for preferred vs required affinity.

The syntax

spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 80
        preference:
          matchExpressions:
          - key: disk
            operator: In
            values: ["ssd"]
      - weight: 20
        preference:
          matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values: ["us-east-1a"]

A list of preferences, each with a weight (1-100) and a preference (matchExpressions). The weights are added to the score for nodes that match.

flowchart LR
    A[Feasible nodes] --> B[Score phase]
    B --> C{Node matches<br/>preference?}
    C -->|yes| D["Score += weight"]
    C -->|no| E[Score unchanged]
    D --> F[Final score]
    E --> F

The weight

The weight is a relative score added to the node’s total:

flowchart TB
    A["Node X<br/>matches preference 1 (weight 80)"] --> B["Score: 80"]
    A2["Node Y<br/>does not match"] --> B2["Score: 0"]
    A3["Node Z<br/>matches preference 2 (weight 20)"] --> B3["Score: 20"]
    A --> C[Other scoring plugins]
    A2 --> C
    A3 --> C
    C --> D["Final score: 80 + other"]
    B2 --> E["Final score: 0 + other"]
    B3 --> F["Final score: 20 + other"]

A higher weight means a stronger preference. With weight: 100 and a node that matches, the node’s score gets a 100-point bonus (out of the maximum 100). With weight: 50, the bonus is 50 points.

Weights are relative, not absolute. A weight: 50 does not mean “50% chance of selection”; it means “50 points added to the score.”

Preferred affinity never blocks

flowchart TB
    A["Pod with preferred<br/>node affinity"] --> B[Filter phase]
    B --> C{All feasible nodes<br/>fail preferences?}
    C -->|yes| D[No bonus added]
    C -->|no| E["Matching nodes get<br/>weight bonus"]
    D --> F["Pod still schedules<br/>on any feasible node"]
    E --> G["Higher-scoring node<br/>wins"]

Unlike required affinity, preferred affinity does not eliminate nodes. If the preference is unsatisfiable, the Pod schedules on any feasible node — possibly with no preference applied.

Combining preferred and required

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/arch
            operator: In
            values: ["amd64"]
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        preference:
          matchExpressions:
          - key: disk
            operator: In
            values: ["ssd"]

The required constraint is arch=amd64 (the Pod must land on an amd64 node). The preferred constraint is disk=ssd (the Pod prefers SSD but is fine with HDD if no SSD is available).

flowchart TB
    A[Filter phase] --> B{Required: arch=amd64}
    B -->|matches| C["Feasible: amd64 nodes"]
    B -->|no match| D[Pending]
    C --> E[Score phase]
    E --> F{Preferred: disk=ssd?}
    F -->|yes| G["Score += 100"]
    F -->|no| H[Score unchanged]
    G --> I[Highest score wins]
    H --> I

When to use which

flowchart TB
    A{Is the constraint<br/>hard or soft?}
    A -->|hard: must satisfy| B[required]
    A -->|soft: prefer but allow fallback| C[preferred]
    B --> D["Pod may be unschedulable<br/>if no node matches"]
    C --> E["Pod always schedules<br/>on any feasible node"]
Use required when…Use preferred when…
The workload cannot run anywhere elseThe workload prefers certain nodes but works elsewhere
Compliance / regulatory pinningLatency, performance, or cost optimisation
Hardware-specific (GPU)Cost-aware placement (prefer cheaper nodes)
Failure mode: Pending PodFailure mode: suboptimal placement

Production patterns

Pattern 1: prefer SSD

preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
  preference:
    matchExpressions:
    - key: disk
      operator: In
      values: ["ssd"]

The workload prefers SSD but runs on HDD if no SSD is available. The weight (80) makes the preference strong but not absolute.

Pattern 2: prefer local zone

preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
  preference:
    matchExpressions:
    - key: topology.kubernetes.io/zone
      operator: In
      values: ["us-east-1a"]

The workload prefers zone us-east-1a for latency. Other zones are fine if us-east-1a is unavailable.

Pattern 3: avoid spot instances

preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
  preference:
    matchExpressions:
    - key: node.kubernetes.io/lifecycle
      operator: NotIn
      values: ["spot"]

The workload prefers on-demand nodes but can run on spot if no on-demand is available.

Pattern 4: combine multiple preferences

preferredDuringSchedulingIgnoredDuringExecution:
- weight: 50
  preference:
    matchExpressions:
    - key: disk
      operator: In
      values: ["ssd"]
- weight: 30
  preference:
    matchExpressions:
    - key: kubernetes.io/arch
      operator: In
      values: ["amd64"]
- weight: 20
  preference:
    matchExpressions:
    - key: topology.kubernetes.io/zone
      operator: In
      values: ["us-east-1a"]

Three preferences with different weights. A node that matches all three gets a 100-point bonus; a node that matches none gets 0.

Failure modes

Failure 1: weight too low to matter

A weight: 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) or ensure the scheduler profile uses the Node Affinity plugin.

Failure 2: preference unsatisfiable

preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
  preference:
    matchExpressions:
    - key: disk
      operator: In
      values: ["ssd"]

If no node has disk=ssd, the Pod schedules anywhere. The preference is silent. Verify the cluster’s labels when the workload is consistently placed on HDD nodes.

Failure 3: required inside preferred

# WRONG: required is not valid in preferred
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
  preference:
    matchExpressions:
    - key: disk
      operator: In
      values: ["ssd"]
      required: true   # not valid here

The required field is for nodeSelector inside nodeSelectorTerms; it does not belong in preferred.

Quiz

Knowledge check · 4 questions

  1. Q1. What does preferredDuringSchedulingIgnoredDuringExecution do?

  2. Q2. A preferredDuringSchedulingIgnoredDuringExecution rule with weight 1 is always meaningful because the scheduler's other plugins have lower weights.

  3. Q3. Your team's web Pods have preferred affinity for SSD nodes with weight 100. The Pods land on HDD nodes. Diagnose.

    Web Pods with preferredDuringSchedulingIgnoredDuringExecution for disk ssd weight 100. Cluster has 4 SSD nodes (all utilised) and 4 HDD nodes (free).

  4. Q4. When should you use preferred node affinity versus required node affinity?

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

Production discipline

  • Use preferred for performance/cost optimisations. A weight of 50-100 with a clear preference is the right shape.
  • Use required for compliance and hardware pinning. A hard constraint with no fallback is the correct shape.
  • Combine preferred and required. A workload can have both: hard on architecture, soft on disk.
  • Verify the weights. A weight: 1 is too low to matter; verify the weight is meaningful (50+) for the preference to have effect.
  • Audit the resulting placement. A dashboard that surfaces the cluster’s node distribution per workload catches preference malfunctions.

Preferred node affinity is the right tool for soft constraints. Operators who choose deliberately have workloads that land predictably.