Kubernetes Scheduling: Taints, Tolerations, and Node Affinity
Control where pods run in your cluster using scheduling constraints.
Node Selectors
Simple way to constrain pods to nodes with specific labels:
spec:
nodeSelector:
disktype: ssd
zone: us-west-1a# Label a node
kubectl label node worker-1 disktype=ssdTaints and Tolerations
Taints are applied to nodes to repel pods. Tolerations are applied to pods to allow scheduling on tainted nodes.
Taint Effects
| Effect | Description |
|---|---|
NoSchedule | Don’t schedule new pods |
PreferNoSchedule | Try to avoid scheduling |
NoExecute | Evict existing + don’t schedule |
Applying Taints
# Add taint
kubectl taint nodes worker-1 key=value:NoSchedule
# Remove taint
kubectl taint nodes worker-1 key=value:NoSchedule-Adding Tolerations
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"Node Affinity
More expressive than nodeSelector:
Required (Hard) Affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: zone
operator: In
values:
- us-west-1a
- us-west-1bPreferred (Soft) Affinity
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssdPod Affinity/Anti-Affinity
Schedule pods relative to other pods:
Pod Affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: cache
topologyKey: kubernetes.io/hostnamePod Anti-Affinity
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostnameCommon Scenarios
- GPU nodes: Taint GPU nodes, tolerate for ML workloads
- Zone spreading: Anti-affinity for HA
- Dedicated nodes: Taint for specific teams
- SSD preference: Node affinity for database pods
Practice Scheduling
Scheduling questions appear in CKA exams. Practice at Sailor.sh.