How to Use Node Affinity in Kubernetes for Pod Scheduling
Use
nodeAffinity in a pod's spec.affinity to specify rules that match node labels for scheduling pods on desired nodes. Node affinity supports requiredDuringSchedulingIgnoredDuringExecution for mandatory rules and preferredDuringSchedulingIgnoredDuringExecution for soft preferences.Syntax
The nodeAffinity field is part of the pod specification under spec.affinity. It has two main types:
- requiredDuringSchedulingIgnoredDuringExecution: Pods must be scheduled on nodes matching these rules.
- preferredDuringSchedulingIgnoredDuringExecution: Pods prefer nodes matching these rules but can schedule elsewhere if none match.
Each rule uses nodeSelectorTerms with matchExpressions to define label key, operator, and values.
yaml
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: <label-key>
operator: In | NotIn | Exists | DoesNotExist | Gt | Lt
values:
- <value1>
- <value2>
preferredDuringSchedulingIgnoredDuringExecution:
- weight: <1-100>
preference:
matchExpressions:
- key: <label-key>
operator: In
values:
- <value>Example
This example schedules a pod only on nodes labeled with disktype=ssd and prefers nodes with zone=us-west.
yaml
apiVersion: v1
kind: Pod
metadata:
name: affinity-example-pod
spec:
containers:
- name: nginx
image: nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: zone
operator: In
values:
- us-westOutput
Pod 'affinity-example-pod' schedules only on nodes with label 'disktype=ssd' and prefers nodes labeled 'zone=us-west'.
Common Pitfalls
Common mistakes include:
- Using
nodeSelectorinstead ofnodeAffinitywhen complex rules are needed. - Misusing operators like
Existswithout values or using invalid operators. - Forgetting that
requiredDuringSchedulingIgnoredDuringExecutionrules are strict and can prevent pod scheduling if no nodes match. - Not labeling nodes properly before applying affinity rules.
yaml
Wrong example:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: Exists
values: [ssd] # Incorrect: 'Exists' operator should not have values
Correct example:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values: [ssd]Quick Reference
| Field | Description | Example |
|---|---|---|
| requiredDuringSchedulingIgnoredDuringExecution | Hard rule; pod schedules only on matching nodes | nodeSelectorTerms with matchExpressions |
| preferredDuringSchedulingIgnoredDuringExecution | Soft rule; pod prefers matching nodes but can schedule elsewhere | weight and preference with matchExpressions |
| matchExpressions.key | Node label key to match | disktype |
| matchExpressions.operator | Operator: In, NotIn, Exists, DoesNotExist, Gt, Lt | In |
| matchExpressions.values | List of label values for the key | [ssd, hdd] |
Key Takeaways
Use nodeAffinity under spec.affinity to control pod placement based on node labels.
requiredDuringSchedulingIgnoredDuringExecution enforces strict node matching for pods.
preferredDuringSchedulingIgnoredDuringExecution sets soft preferences for node selection.
MatchExpressions define label keys, operators, and values to filter nodes.
Always label your nodes correctly before applying node affinity rules.