Skip to main content

Configuring Node Affinity

1. Using requiredDuringScheduling

The requiredDuringScheduling affinity rule ensures that pods are only scheduled onto nodes that match specific criteria. This is a hard requirement, meaning the pod will not be scheduled if no matching node is found.

Field Description Values
nodeSelectorTerms Defines the set of node labels that must be present on a node for scheduling. array of NodeSelectorTerm
matchExpressions Defines a set of key-value pairs that must match node labels. array of NodeSelectorRequirement

Example: Node Affinity with requiredDuringScheduling

apiVersion: v1
kind: Pod
metadata:
  name: affinity-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
  containers:
  - name: main-container
    image: nginx
Note: The requiredDuringSchedulingIgnoredDuringExecution field ensures that the affinity rules are enforced during scheduling, but not during the pod's lifecycle once it is running.

2. Using preferredDuringScheduling

The preferredDuringScheduling affinity rule allows you to specify preferences for node placement, which are not strict requirements. These preferences are evaluated during the scheduling phase but do not prevent a pod from being scheduled if the preferred nodes are unavailable.

Field Description Example
preferredDuringSchedulingIgnoredDuringExecution Defines a list of preferences for node scheduling. These are soft constraints that the scheduler will try to honor but won't prevent scheduling if not met.
{
  "preferredDuringSchedulingIgnoredDuringExecution": [
    {
      "weight": 1,
      "preference": {
        "matchExpressions": [
          {
            "key": "topology.kubernetes.io/zone",
            "operator": "In",
            "values": ["us-west-1a"]
          }
        ]
      }
    }
  ]
}

Example: Preferred Node Affinity

apiVersion: v1
kind: Pod
metadata:
  name: affinity-pod
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - us-west-1a
  containers:
  - name: app-container
    image: nginx
Note: The preferredDuringSchedulingIgnoredDuringExecution rule is evaluated only during pod scheduling and does not affect the pod's behavior once it is running.

3. Configuring Node Selectors

Property Value Description
nodeSelector { "key": "value" } Simple key-value pairs to match node labels

Example: Setting Node Selector

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  nodeSelector:
    kubernetes.io/os: linux
    disktype: ssd
  containers:
  - name: nginx
    image: nginx
Note: nodeSelector is a simple label match and does not support operators like notIn or exists. For more complex affinity rules, use nodeAffinity.

4. Using matchExpressions

Field Description Values Notes
key Required. The label key to match. string Must be a valid label key.
operator Required. The operator to use for matching. In, NotIn, Exists, DoesNotExist, Gt, Lt Operators like Gt and Lt require a numeric value.
values Optional. The set of values to match against. array Used with In and NotIn operators.

Example: matchExpressions with In operator

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/e2e-az-name
              operator: In
              values:
                - e2e-az1
                - e2e-az2

Example: matchExpressions with Gt operator

affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
            - key: node.kubernetes.io/cpu
              operator: Gt
              values:
                - "2"

5. Setting Node Label Selectors

Property Description Values Notes
nodeSelector Simple label-based selector for nodes {"label-key": "label-value"} Matches nodes with the specified label key and value
nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution Hard requirement for node labels {nodeSelector: {nodeSelectorTerms: [{matchExpressions: [{key: "label-key", operator: "In", values: ["value1"]}]}]} Must match for scheduling
nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution Soft requirement for node labels {nodeSelectorTerms: [{matchExpressions: [{key: "label-key", operator: "In", values: ["value1"]}]}]} Preferred but not mandatory

Example: Setting Node Label Selectors

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  nodeSelector:
    kubernetes.io/hostname: node-1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-label-key
            operator: In
            values:
            - another-label-value

6. Combining Multiple Affinity Rules

Rule Type Description Example
nodeSelector Matches nodes based on labels using key-value pairs
nodeSelector:
  kubernetes.io/os: linux
nodeAffinity Enables more complex matching using requiredDuringSchedulingIgnoredDuringExecution and preferredDuringSchedulingIgnoredDuringExecution
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/e2e-az-name
          operator: In
          values:
          - e2e-az1
          - e2e-az2
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: another-node-label-key
          operator: In
          values:
          - another-node-label-value
podAffinity Controls scheduling based on labels of already-running pods
affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: myapp
      topologyKey: kubernetes.io/hostname
podAntiAffinity Ensures pods are not scheduled on nodes with matching labels
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app: myapp
        topologyKey: kubernetes.io/hostname

Example: Combining nodeSelector and nodeAffinity

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  nodeSelector:
    kubernetes.io/os: linux
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: node-type
            operator: In
            values:
            - production

Example: Using podAntiAffinity to avoid duplicate pods

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app: web
        topologyKey: kubernetes.io/hostname

7. Using Node Anti-Affinity

Node anti-affinity ensures that pods are scheduled to different nodes, preventing colocating pods from the same set on the same node. This is useful for high availability and avoiding resource contention.

Field Description Values Notes
nodeSelectorTerms Defines the terms to match node labels list of NodeSelectorTerm Used in conjunction with preferredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution Soft constraint for preferred scheduling list of PreferredSchedulingTerm Does not guarantee anti-affinity, but prefers scheduling pods on different nodes
requiredDuringSchedulingIgnoredDuringExecution Hard constraint for scheduling list of NodeSelectorTerm Ensures pods are not scheduled on nodes matching the specified criteria

Example: Anti-Affinity with Label Match

apiVersion: v1
kind: Pod
metadata:
  name: anti-affinity-pod
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          preference:
            matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                  - us-west-1a
                  - us-west-1b
  containers:
    - name: app-container
      image: nginx

Example: Hard Anti-Affinity Using Node Selector

apiVersion: v1
kind: Pod
metadata:
  name: hard-anti-affinity-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: node-role.kubernetes.io/control-plane
                operator: DoesNotExist
  containers:
    - name: app-container
      image: nginx
Note: Node anti-affinity is often used in combination with pod anti-affinity to ensure that pods from the same application or workload are not scheduled on the same node.

8. Setting Weight Priority

Field Description Values Notes
weight Weight for the node affinity rule 0-100 Higher weight increases preference

Example: Node Affinity with Weight

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 80
          preference:
            matchExpressions:
              - key: node-type
                operator: In
                values:
                  - production
  containers:
    - name: nginx
      image: nginx

9. Using IgnoredDuringExecution

Field Description Values Notes
nodeSelector Matches node labels to schedule pods null or {key: value} Simple label matching; not flexible for complex constraints
affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution Required node affinity rules to schedule pods null or {nodeSelectorTerms: [...]} Pods must match at least one term to be scheduled
affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution Preferred node affinity rules to schedule pods null or [{weight: int, preference: {matchExpressions: [...]}}] Pods prefer to schedule on nodes matching terms, but not required

Example: Node Affinity with IgnoredDuringExecution

apiVersion: v1
kind: Pod
metadata:
  name: affinity-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: kubernetes.io/e2e-az-name
                operator: In
                values:
                  - e2e-az1
                  - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
            matchExpressions:
              - key: another-node-label-key
                operator: In
                values:
                  - another-node-label-value
  containers:
    - name: main-container
      image: nginx
Note: The IgnoredDuringExecution part means that once a pod is scheduled, it will continue running even if node labels change and no longer match the affinity rules.

10. Troubleshooting Affinity Rules

Example: Debugging Node Affinity Issues

kubectl describe pod <pod-name> | grep -i affinity
Issue Symptoms Resolution
Node Taints Pod remains in Pending state Check node taints with kubectl describe nodes
Label Mismatch Pod fails to schedule due to missing labels Verify node labels with kubectl get nodes --show-labels
Operator Misuse Incorrect MatchExpressions syntax Validate affinity rules in YAML format
Note: Use kubectl logs <pod-name> to check for scheduling errors in pod events.
Warning: Affinity rules can conflict with taints and tolerations; ensure they are aligned.

Was this article helpful?