Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Apply Taints and Tolerations to Nodes

Learn to apply taints and tolerations to nodes in Kubernetes. This hands-on tutorial covers core concepts, step-by-step exercises, troubleshooting, and edge cases for scheduling control.

Focus: apply taints and tolerations to nodes

Sponsored

You've built clusters, scheduled Pods, and maybe even tamed a DaemonSet. But what happens when a critical Pod must run on a specific node, or when a node is so special that nothing else should touch it? Without taints and tolerations, the scheduler treats every node as equally eligible—leading to resource conflicts, security leaks, or workloads landing on the wrong hardware. Let's fix that.

The problem this lesson solves

Imagine a cluster with a GPU-equipped node reserved exclusively for machine learning training. Without taints, the scheduler will scatter web servers and databases onto that expensive GPU machine, wasting capacity and blocking critical jobs. Or consider a node with specialized compliance software—allowing general Pods to land there violates audit requirements.

The default scheduling policy is permissive: if a node has resources, the scheduler will happily place Pods there. This becomes a liability when you need to dedicate nodes to specific workloads, restrict access to sensitive Pods, or protect critical infrastructure from accidental eviction. Taints and tolerations solve this by letting nodes repel Pods unless those Pods explicitly declare they can tolerate the node.

Core concept / mental model

Think of taints as "No Trespassing" signs on a node, and tolerations as the special badge that lets certain Pods pass through. A node can have one or more taints; a Pod must have matching tolerations to be scheduled on that node.

What is a taint?

A taint is a key-value pair with an effect attached to a node. The effect tells the scheduler what to do with Pods that don't tolerate the taint:

  • NoSchedule — Don't schedule new Pods unless they tolerate it.
  • PreferNoSchedule — Soft version: try to avoid, but not guaranteed.
  • NoExecute — Evict existing Pods that don't tolerate, in addition to preventing new ones.

What is a toleration?

A toleration is a matching rule on a Pod that says "I can handle this taint." It must specify the same key, value (if the taint uses a value), and effect.

Pro tip: Tolerations are not permissions to choose a node—they only allow a Pod to be scheduled on a tainted node if it already matches other scheduling constraints. Use node affinity for positive selection, tolerations for negative filtering.

How it works step by step

  1. Apply a taint to a node using kubectl taint nodes <node> key=value:effect.
  2. When the scheduler evaluates node suitability for a Pod, it checks the node's taints.
  3. If the Pod has a toleration matching all taints with effect NoSchedule or NoExecute, the node is considered schedulable.
  4. For NoExecute, any running Pods that lack the toleration are evicted immediately.
  5. PreferNoSchedule is advisory—the scheduler avoids the node but may still use it if no other node fits.

Taint structure

A taint is defined as key=value:Effect. The value is optional—you can have key:Effect (value empty). Multiple taints on a node are OR'ed: the Pod must tolerate all non-optional taints to be scheduled.

Toleration matching rules

A toleration can match by: - Exact key, value, and effect - Key and effect only (value omitted, signified by operator: "Exists") - Operator Exists with no key (tolerates everything, rarely used)

Hands-on walkthrough

Prerequisites

  • A running Kubernetes cluster (minikube works)
  • kubectl configured

Step 1: Taint a node

First, get your node names:

kubectl get nodes

Assume you have a node named gpu-node. Add a taint that says "only ML workloads allowed":

kubectl taint nodes gpu-node gpu=true:NoSchedule

Verify the taint:

kubectl describe node gpu-node | grep Taints

Expected output (truncated):

Taints:             gpu=true:NoSchedule

Step 2: Schedule a Pod without toleration

Create web-pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: web-server
spec:
  containers:
  - name: nginx
    image: nginx:1.25

Apply it:

kubectl apply -f web-pod.yaml
kubectl get pods -o wide

You'll see the Pod stuck in Pending because no node tolerates the taint (unless other untainted nodes exist). The gpu-node has NoSchedule, so the scheduler avoids it.

Step 3: Schedule a Pod with toleration

Create ml-pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: ml-training
spec:
  containers:
  - name: pytorch
    image: pytorch/pytorch:latest
    command: ["sleep", "3600"]
  tolerations:
  - key: "gpu"
    operator: "Equals"
    value: "true"
    effect: "NoSchedule"

Apply and check:

kubectl apply -f ml-pod.yaml
kubectl get pods -o wide

The Pod should land on gpu-node because its toleration matches the node taint.

Step 4: Test NoExecute

Add a NoExecute taint to a different node (e.g., db-node):

kubectl taint nodes db-node critical=true:NoExecute

Now any Pod running on db-node without a toleration critical=true:NoExecute will be evicted. Start a test Pod on db-node first (maybe using nodeName), then apply the taint—you'll see the Pod get terminated.

Compare options / when to choose what

Effect Behavior Use case
NoSchedule Blocks new Pods without toleration Dedicated nodes for production workloads
PreferNoSchedule Soft avoidance, best-effort Reducing load on special hardware without strict enforcement
NoExecute Blocks new + evicts existing without toleration Maintenance drains, security isolation
No taint Default General-purpose nodes

When to use taints vs node affinity? - Taints + tolerations: Keep Pods off a node unless they specifically opt in. Good for specialized hardware, compliance zones. - Node affinity: Attract Pods to a node using labels. Good for ensuring Pods run on specific node groups like zone=us-east. - Combine both: Use node affinity to pull Pods to a node pool, and taints to prevent other Pods from landing there.

Troubleshooting & edge cases

Pod stuck in Pending

  • Check node taints: kubectl describe node <node>
  • Verify Pod tolerations match exactly (key, value, effect)
  • Ensure operator is Equals (default) or Exists — misspelling Equal causes silent mismatch

Evicted pods after NoExecute

  • Pods without matching toleration get deleted. Use kubectl get events --watch to see eviction
  • Ensure critical system Pods (like kube-proxy, coredns) have tolerations for control-plane taints

Toleration doesn't match

  • Taint value gpu=true:NoSchedule requires toleration with value: "true" and effect: "NoSchedule". Omitting value with operator: "Exists" works, but only if you set operator: "Exists" explicitly.
  • Common mistake: using operator: Equal instead of operator: "Equals" (case-sensitive — Equal is invalid).

Node already tainted

  • kubectl taint will append new taints unless you use --overwrite. To remove: kubectl taint nodes <node> key:NoSchedule- (hyphen at the end).

What you learned & what's next

You now understand the core purpose of taints and tolerations: giving nodes the ability to repel Pods and letting Pods opt in to restricted nodes. You've applied NoSchedule, PreferNoSchedule, and NoExecute taints, scheduled both non-tolerant and tolerant Pods, and seen eviction in action. You can now implement dedicated node pools, protect sensitive hardware, and enforce scheduling policies.

Next up: Master node affinity to actively pull Pods toward specific nodes using labels — the counterpart to taints. In the next lesson, you'll combine both concepts to build precise, production-grade scheduling rules.

Practice recap

Create a second node (or use an existing one) and assign it a taint env=prod:NoSchedule. Then deploy two Deployments: one for a web app without toleration (should land on non-tainted nodes), and another for a monitoring agent with a matching toleration (should land on the tainted node). Use kubectl get pods -o wide to verify placement.

Common mistakes

  • Misspelling the toleration operator as Equal instead of Equals — Kubernetes accepts only Equals
  • Forgetting to specify the effect in toleration when the taint has one — leads to silent scheduling failure
  • Applying NoExecute taint without testing on non-critical Pods first — causes unexpected eviction waves
  • Assuming a toleration gives a Pod priority or preference — tolerations only allow scheduling, they don't actively choose the node

Variations

  1. Use kubectl taint with --overwrite to replace an existing taint with the same key:effect instead of adding a duplicate
  2. Use operator: Exists without specifying value to tolerate any value for a given key — useful for key-based filtering
  3. Define taints at node pool level in cloud providers (AKS, EKS, GKE) so all nodes in the pool inherit them

Real-world use cases

  • Dedicate GPU nodes in an AKS cluster exclusively to ML training Pods by applying nvidia.com/gpu=true:NoSchedule taint
  • Isolate PCI-compliant workloads on dedicated nodes in a GKE cluster, preventing non-compliant Pods from landing there
  • Use NoExecute taint to gracefully drain nodes for kernel updates — system Pods with tolerations survive, others are rescheduled

Key takeaways

  • Taints repel Pods from nodes; tolerations allow Pods to be scheduled on tainted nodes
  • The three taint effects are NoSchedule, PreferNoSchedule, and NoExecute — each with distinct behavior for scheduling and eviction
  • Tolerations must match the taint's key, value (if present), and effect using the correct operator (Equals or Exists)
  • Taints are for restriction; use node affinity for attraction — combine both for precise scheduling
  • NoExecute evicts running Pods that don't tolerate — test carefully before applying to production nodes
  • Taints can be added, removed, or overwritten with --overwrite using kubectl taint

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.