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. | |
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 | |
| nodeAffinity | Enables more complex matching using requiredDuringSchedulingIgnoredDuringExecution and preferredDuringSchedulingIgnoredDuringExecution |
|
| podAffinity | Controls scheduling based on labels of already-running pods | |
| podAntiAffinity | Ensures pods are not scheduled on nodes with matching labels | |
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
| 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.