iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
<p>Use <code>nodeSelector</code> when a Pod may run only on nodes that carry every label you list. Use node affinity when you need alternatives (OR logic), operators such as <code>NotIn</code> or <code>Exists</code>, or a soft preference the scheduler should try to honour but may skip. If a Pod sets both, both sets of rules must be satisfied. A preference is never a guarantee: a Pod with only a preferred rule can still land on a node that does not match it.</p><p>The Kubernetes task guide <a href=”https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/”>Assigning Pods to Nodes</a> is the canonical reference, but it is a rolling page. Before copying a manifest into production, check the documentation version that matches your cluster release for exact field names and behaviour.</p>
<h2>Label the nodes first</h2><p>Both mechanisms match against node labels, so the first step is to see what labels exist and to add the ones your policy needs.</p><ol><li>List the labels on every node: <code>kubectl get nodes –show-labels</code></li><li>Add a label to a node: <code>kubectl label nodes worker-2 disktype=ssd</code></li><li>Confirm which nodes carry it: <code>kubectl get nodes -l disktype=ssd</code></li><li>Remove it when it is no longer needed: <code>kubectl label nodes worker-2 disktype-</code></li></ol><p>Some labels are populated by Kubernetes or by the cloud platform rather than by you. The official guide cautions that some standard label values are provider-specific. For example, <code>kubernetes.io/hostname</code> may or may not equal the node name, depending on the environment. Check the value with <code>–show-labels</code> before you build a selector on it.</p><h2>nodeSelector: the simplest form</h2><p><code>nodeSelector</code> sits directly in the Pod specification as a map of label keys and values. The scheduler places the Pod only on a node that has every listed label with the listed value. The official guide calls it the simplest recommended form of node selection constraint.</p><pre><code>apiVersion: v1nkind: Podnmetadata:n name: ssd-appnspec:n nodeSelector:n disktype: ssdn team: batchn containers:n – name: appn image: nginxn</code></pre><p>In that example a node needs both <code>disktype=ssd</code> and <code>team=batch</code>. A node with only one of them is not eligible. What <code>nodeSelector</code> cannot do is express alternatives (ssd or nvme), exclusions (not spot), or preferences. Those cases call for node affinity.</p><h2>Node affinity</h2><p>Node affinity is configured under <code>.spec.affinity.nodeAffinity</code>. It offers two forms with different behaviour, and you can use either or both.</p><h3>Required rules</h3><p>A rule under <code>requiredDuringSchedulingIgnoredDuringExecution</code> is a hard requirement. The scheduler cannot place the Pod on a node that fails it. If no node qualifies, the Pod remains unscheduled.</p><h3>Preferred rules</h3><p>A rule under <code>preferredDuringSchedulingIgnoredDuringExecution</code> is a soft preference. The scheduler tries to find a node that satisfies it, but if none is available it places the Pod on another feasible node. Each preferred entry carries a <code>weight</code> from 1 to 100. The scheduler adds the weights of the preferred rules a candidate node satisfies and combines that total with scores from other scheduling priority functions. A high weight therefore makes a preferred node more likely to win the ranking, but it does not guarantee that the Pod lands there.</p><p>The example below combines both forms. Pods must run on a node labelled with an NVIDIA A100 or H100 accelerator, and they prefer a rack labelled <code>failure-domain=rack-a</code>.</p><pre><code>apiVersion: v1nkind: Podnmetadata:n name: train-jobnspec:n affinity:n nodeAffinity:n requiredDuringSchedulingIgnoredDuringExecution:n nodeSelectorTerms:n – matchExpressions:n – key: acceleratorn operator: Inn values: [nvidia-a100, nvidia-h100]n preferredDuringSchedulingIgnoredDuringExecution:n – weight: 80n preference:n matchExpressions:n – key: failure-domainn operator: Inn values: [rack-a]n containers:n – name: trainn image: registry.example.com/train:1.0n</code></pre><p>Keep the required and preferred sections separate when you adapt this. Moving a rule from one section to the other changes whether the Pod can be scheduled at all.</p><h3>What happens when labels change later</h3><p>The suffix <code>IgnoredDuringExecution</code> means that rules are evaluated only at scheduling time. If you later remove or change a node label that a running Pod depended on, the Pod keeps running. Node affinity does not evict it.</p><h2>How terms, expressions, and selectors combine</h2><p>Placement logic is easy to misread because the same word, such as “multiple”, means AND in one place and OR in another. The table below sets out the rules.</p><table><thead><tr><th>Situation</th><th>How the conditions combine</th><th>Effect on placement</th></tr></thead><tbody><tr><td>Both <code>nodeSelector</code> and <code>nodeAffinity</code> are set</td><td>AND</td><td>A node must satisfy both before it is eligible.</td></tr><tr><td>Several <code>nodeSelectorTerms</code> under required affinity</td><td>OR</td><td>A node that satisfies any one term is eligible.</td></tr><tr><td>Several <code>matchExpressions</code> inside one term</td><td>AND</td><td>A node must satisfy every expression in that term.</td></tr><tr><td>Several preferred entries</td><td>Weights are added for each satisfied entry</td><td>Affects ranking among eligible nodes only; never excludes a node.</td></tr></tbody></table><p>The operators available in node affinity expressions are listed below.</p><table><thead><tr><th>Operator</th><th>Matches when</th></tr></thead><tbody><tr><td><code>In</code></td><td>The label value is one of the listed values.</td></tr><tr><td><code>NotIn</code></td><td>The label value is not any of the listed values. Nodes without the key also satisfy it.</td></tr><tr><td><code>Exists</code></td><td>The label key is present, whatever its value.</td></tr><tr><td><code>DoesNotExist</code></td><td>The label key is absent.</td></tr><tr><td><code>Gt</code></td><td>The node label value, read as an integer, is greater than the single listed integer. Node affinity only.</td></tr><tr><td><code>Lt</code></td><td>The node label value, read as an integer, is less than the single listed integer. Node affinity only.</td></tr></tbody></table><p><code>Gt</code> and <code>Lt</code> are integer comparisons. A label value that is not an integer will not match them, so do not use them for names or version strings.</p><h2>Choosing between nodeSelector and node affinity</h2><p>The two mechanisms overlap, and the choice depends on how much logic the policy needs. The table compares them on the axes that usually decide it.</p><table><thead><tr><th>Criterion</th><th>nodeSelector</th><th>Node affinity</th></tr></thead><tbody><tr><td>Rule shape</td><td>Equality match; every listed label must match</td><td>Operators, OR across terms, AND within a term</td></tr><tr><td>Hard constraint</td><td>Yes</td><td>Yes, through the required form</td></tr><tr><td>Soft preference</td><td>Not available</td><td>Yes, through the preferred form with weights 1 to 100</td></tr><tr><td>Exclusions and existence checks</td><td>Not available</td><td>Available (<code>NotIn</code>, <code>DoesNotExist</code>)</td></tr><tr><td>Readability</td><td>Short and easy to review</td><td>Longer; errors in nesting are easy to make</td></tr></tbody></table><p>Kubernetes documentation recommends letting the scheduler make reasonable placement decisions when special constraints are not needed. Add constraints only when a real requirement exists.</p><ul><li>Use <code>nodeSelector</code> when a Pod needs one or more labels and no alternatives.</li><li>Use required node affinity when the Pod needs OR logic, operators, or exclusions, and it must not run elsewhere.</li><li>Use preferred node affinity when a node type is better but any feasible node is acceptable.</li><li>Combine both forms when a hard requirement and a soft preference apply to the same Pod.</li></ul><h2>Isolation labels and who can change them</h2><p>If you use node labels to keep workloads apart, for example to separate tenants or to mark regulated hardware, the label is only as trustworthy as the process that can set it. The official guide advises choosing label keys that the kubelet cannot modify.</p><p>Kubernetes provides that protection through the <code>NodeRestriction</code> admission plugin. It blocks kubelets from setting or modifying labels with the <code>node-restriction.kubernetes.io/</code> prefix. To rely on it:</p><ol><li>Enable the Node authorizer and the <code>NodeRestriction</code> admission plugin on the API server.</li><li>Apply the isolation labels with the <code>node-restriction.kubernetes.io/</code> prefix, using an administrator identity, for example <code>kubectl label node worker-2 node-restriction.kubernetes.io/tenant=finance</code>.</li><li>Reference the same key in <code>nodeSelector</code> or node affinity.</li></ol><p>A label name alone does not make a placement rule secure. Without the admission and authorization settings above, a label can be changed by whoever is able to modify Node objects.</p><h2>When a Pod stays Pending despite a rule</h2><p>A matching selector is not a promise that the Pod will start. Other factors can keep it from scheduling:</p><ul><li>No node carries the required labels, or the matching nodes are full.</li><li>Taints on matching nodes repel the Pod unless it has a matching toleration.</li><li>Other scheduling requirements, such as resource requests or scheduler configuration, leave no feasible node.</li></ul><p>To diagnose a Pending Pod, start by checking which nodes match the rule, for example <code>kubectl get nodes -l accelerator=nvidia-a100</code>. Then run <code>kubectl describe pod train-job</code> and read the Events section, which reports why each node was rejected. The exact wording of those messages varies between Kubernetes releases. A preferred rule never produces this kind of Pending state on its own, because the scheduler falls back to any feasible node.</p>
Quick Recap
#1 Best Overall
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →

