Skip to main content
This article explains how to combine Kubernetes taints & tolerations with node affinity to place pods onto specific nodes and keep other pods off those nodes. It uses a simple, concrete example to show why each mechanism alone is insufficient for exclusive node assignment and how using both together provides the desired exclusivity.

Scenario

  • A cluster contains many nodes and pods from multiple teams.
  • We have three color-specific nodes and three pods: blue, red, and green.
  • Goal: schedule the blue pod on the blue node, the red pod on the red node, and the green pod on the green node.
  • Additional requirement: prevent other teams’ pods from being scheduled onto our three color-specific nodes, and prevent our pods from being scheduled onto other (non-colored) nodes.

First approach — Taints and Tolerations

Taints are applied to nodes to repel pods that do not explicitly tolerate those taints. Tolerations are added to pods to allow them to be scheduled onto tainted nodes. Example: taint the blue node so it repels non-tolerant pods:
Give the blue pod a toleration for that taint:
Behavior and caveats:
  • The blue pod can be scheduled on the blue node because it tolerates the blue taint.
  • Tolerations only allow placement on tainted nodes; they do not force placement onto specific nodes.
  • A pod with the toleration may still be scheduled onto any other node that meets scheduling constraints (including untainted nodes).
  • Therefore, taints + tolerations alone do not guarantee that pods will end up only on the intended labeled nodes.

Second approach — Node Affinity

Node affinity uses node labels to require or prefer that pods run on nodes with specific labels. Node affinity can constrain a pod to nodes labeled with a matching value. Label the nodes by color:
Use required node affinity on the pod to ensure it only schedules on nodes with the matching label:
A stylized infographic titled "Node Affinity" showing five server node illustrations with colored cube icons above them. Three nodes are highlighted in blue, red, and green and labeled Node 1, Node 2, and Node 3, with the remaining slots shown as other nodes.
Behavior and caveats:
  • Required node affinity forces the pod to be scheduled only on nodes whose labels satisfy the rule (e.g., nodes labeled color=blue).
  • Node affinity alone does not prevent other pods from being scheduled onto the same nodes. Other teams’ pods can still land on the blue node unless they are repelled.

To create effectively dedicated nodes, combine both mechanisms:
  • Taint each color node to repel all pods that do not tolerate that taint.
  • Label each node with its color.
  • Add a toleration to only the corresponding color pod so it can be scheduled onto the tainted node.
  • Use required node affinity in the pod spec so the pod can only schedule onto the correctly labeled node.
Combined steps (for the blue node/pod):
  1. Taint the node:
  1. Label the node:
  1. Pod spec includes both tolerations and required node affinity:
Result:
  • The taint prevents unrelated pods (without the matching toleration) from being scheduled onto the node.
  • The pod’s toleration allows it to be scheduled onto the tainted node.
  • The pod’s required node affinity forces it to target the specifically labeled node.
  • Together, this creates an effectively dedicated node for that pod (repeat same configuration for red and green).

Comparison at a glance


Use required node affinity (requiredDuringSchedulingIgnoredDuringExecution) to force a pod onto specific labeled nodes. Use taints with effect NoSchedule on those nodes to repel other pods; then add tolerations only to the pods you want to run there. If you want softer preferences instead of hard guarantees, consider preferredDuringSchedulingIgnoredDuringExecution, but that does not provide exclusivity.
This combination gives you predictable placement (node affinity) and exclusivity (taints + tolerations), which together satisfy the requirement to dedicate specific nodes to specific workloads.

Watch Video