Working with Tolerations
Now that we understand how taints work, let's explore tolerations - the mechanism that allows pods to be scheduled on tainted nodes.
Understanding Tolerations
Tolerations are specified in pod specifications and allow pods to be scheduled on nodes with matching taints. A toleration consists of:
key
: Matches the taint key
operator
: Either Equal
(matches key and value) or Exists
(matches just the key)
value
: The value to match (when using the Equal
operator)
effect
: The effect to match, or empty to match all effects
tolerationSeconds
: Optional duration for which the pod can remain on a node with a matching NoExecute taint
Creating a Pod with Tolerations
Let's create a pod that tolerates our control-plane taint. First, let's create a YAML file for our pod:
nano ~/project/toleration-pod.yaml
Now, add the following content to the file:
apiVersion: v1
kind: Pod
metadata:
name: toleration-pod
spec:
containers:
- name: nginx
image: nginx:latest
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
This pod specification includes a toleration that matches the control-plane taint on our node. Save and exit the file (in nano, press Ctrl+O
, Enter
, then Ctrl+X
).
Now, let's create the pod:
kubectl apply -f ~/project/toleration-pod.yaml
You should see output like:
pod/toleration-pod created
Let's check if the pod was scheduled on our node:
kubectl get pods -o wide
Example output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
toleration-pod 1/1 Running 0 12s 10.244.0.5 minikube <none> <none>
The pod is running on our minikube node because it has a toleration matching the control-plane taint.
Testing with a Pod without Tolerations
For comparison, let's create a pod without tolerations:
nano ~/project/no-toleration-pod.yaml
Add the following content:
apiVersion: v1
kind: Pod
metadata:
name: no-toleration-pod
spec:
containers:
- name: nginx
image: nginx:latest
Save and exit the file, then create the pod:
kubectl apply -f ~/project/no-toleration-pod.yaml
Now, let's check the pod status:
kubectl get pods -o wide
You might notice that the pod remains in a Pending state:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
no-toleration-pod 0/1 Pending 0 12s <none> <none> <none> <none>
toleration-pod 1/1 Running 0 2m 10.244.0.5 minikube <none> <none>
Let's check why the pod is pending:
kubectl describe pod no-toleration-pod
In the events section, you should see something like:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 45s default-scheduler 0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.
This confirms that the pod could not be scheduled because it doesn't tolerate the control-plane taint.
Cleanup
Let's clean up the pods we created:
kubectl delete pod toleration-pod no-toleration-pod
You should see:
pod "toleration-pod" deleted
pod "no-toleration-pod" deleted
Congratulations! You now understand how taints and tolerations work together to control pod scheduling in Kubernetes.