CKA Certification Course - Certified Kubernetes Administrator
Scheduling
Solution Taints and Toleration Optional
In this guide, you will learn how to work with taints and tolerations in Kubernetes. We start by inspecting the cluster nodes, then proceed to apply a taint to a node and create pods with and without the appropriate tolerations.
Step 1: Count the Nodes
Begin by verifying the total number of nodes (including the control plane) in your cluster. Run the following command:
root@controlplane:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
controlplane Ready control_plane,master 17m v1.20.0
node01 Ready <none> 16m v1.20.0
root@controlplane:~#
There are two nodes in the cluster.
Note
This output confirms that both the control plane and node01 are active and ready.
Step 2: Check Taints on node01
Next, examine node01 for any existing taints. Use the kubectl describe
command:
root@controlplane:~# kubectl describe node node01
Name: node01
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=node01
kubernetes.io/os=linux
Annotations: flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"8e:62:74:26:35:47"}
flannel.alpha.coreos.com/backend-type: vxlan
flannel.alpha.coreos.com/kube-subnet-manager: true
flannel.alpha.coreos.com/public-ip: 10.58.27.11
kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Fri, 15 Apr 2022 22:57:19 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: node01
AcquireTime: <unset>
RenewTime: Fri, 15 Apr 2022 23:14:20 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason
---- ------ ----------------- --------------------- ----------------
NetworkUnavailable False Fri, 15 Apr 2022 22:57:25 +0000 Fri, 15 Apr 2022 22:57:25 +0000 Flannel is running on this node
MemoryPressure False Fri, 15 Apr 2022 23:12:35 +0000 Kubelet has sufficient memory available
DiskPressure False Fri, 15 Apr 2022 23:11:20 +0000 Kubelet has no disk pressure
...
root@controlplane:~#
Since there are no taints on node01, you can conclude that there are no scheduling constraints for pods on this node at this moment.
Step 3: Apply a Taint on node01
Now, add a taint to node01 by specifying a key-value pair and an effect. The command below applies a taint with the key "spray", a value of "mortein", and an effect of "NoSchedule":
kubectl taint node node01 spray=mortein:NoSchedule
This taint ensures that only pods with a matching toleration will be scheduled on node01.
Step 4: Create the "mosquito" Pod Without a Toleration
Create a pod named "mosquito" using the nginx image without specifying any toleration:
root@controlplane:~# kubectl run mosquito --image=nginx
After creating the pod, check its status:
root@controlplane:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
mosquito 0/1 Pending 0 3m37s
root@controlplane:~#
Since the pod lacks a toleration for the taint applied on node01, it remains in a pending state. To investigate further, describe the pod:
root@controlplane:~# kubectl describe pod mosquito
Name: mosquito
Namespace: default
Priority: 0
Node: <none>
Labels: run=mosquito
Status: Pending
Containers:
mosquito:
Image: nginx
Port: <none>
Host Port: <none>
...
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Warning FailedScheduling 45s (x2 over 45s) default-scheduler 0/2 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 1 node(s) had taint {spray: mortein:NoSchedule}, that the pod didn't tolerate.
...
root@controlplane:~#
The event message clarifies that "mosquito" cannot be scheduled due to the untolerated "spray" taint on node01.
Warning
Ensure that you add the proper tolerations when you need a pod to be scheduled on a tainted node.
Step 5: Create the "bee" Pod With a Toleration
To schedule a pod on node01 despite the taint, create a new pod named "bee" with a toleration for "spray". Follow these steps:
Generate an initial YAML manifest using dry-run:
kubectl run bee --image=nginx --dry-run=client -o yaml > bee.yaml
Open the generated
bee.yaml
file and add atolerations
section under the spec. The corrected YAML should resemble the following:apiVersion: v1 kind: Pod metadata: name: bee labels: run: bee spec: containers: - name: bee image: nginx resources: {} dnsPolicy: ClusterFirst restartPolicy: Always tolerations: - key: "spray" operator: "Equal" value: "mortein" effect: "NoSchedule"
Apply the manifest to create the pod:
kubectl apply -f bee.yaml
Monitor the pod creation:
kubectl get pods --watch
After a few seconds, you should see the "bee" pod transition to the Running state. Verify the status by running:
root@controlplane:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
bee 1/1 Running 0 36s 10.244.1.2 node01 <none> <none>
mosquito 0/1 Pending 0 4m6s <none> <none> <none>
root@controlplane:~#
The "bee" pod successfully schedules on node01 because it contains the correct toleration, while "mosquito" continues to remain pending.
Step 6: Remove the Taint from the Control Plane
Finally, inspect the control plane node to confirm it has a taint restricting regular pod scheduling:
root@controlplane:~# kubectl describe node controlplane
Name: controlplane
Roles: control-plane,master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=controlplane
node-role.kubernetes.io/control-plane=
Annotations: flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"f6:6e:ba:7d:23:ca"}
flannel.alpha.coreos.com/backend-type: vxlan
flannel.alpha.coreos.com/kube-subnet-manager: true
kubeadm.alpha.coreos.com/cri-socket: /var/run/dockershim.sock
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Fri, 15 Apr 2022 22:56:44 +0000
Taints: node-role.kubernetes.io/master:NoSchedule
Unschedulable: false
...
root@controlplane:~#
To allow pods to be scheduled on the control plane, remove its taint with the following command:
kubectl taint node controlplane node-role.kubernetes.io/master:NoSchedule-
Once the taint is removed, the "mosquito" pod can now find a suitable node. Confirm the new pod status:
root@controlplane:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
bee 1/1 Running 0 2m52s 10.244.1.2 node01 <none> <none>
mosquito 1/1 Running 0 6m22s 10.244.0.4 controlplane <none> <none>
root@controlplane:~#
Now, "mosquito" is running on the control plane since the scheduling conflict has been resolved.
Summary
This walkthrough demonstrates the use of taints and tolerations to control pod placement in a Kubernetes cluster:
- Initially, node01 had a taint (
spray=mortein:NoSchedule
) and the control plane had the default master taint, which prevented the "mosquito" pod from scheduling. - Creating the "bee" pod with the appropriate toleration allowed it to be scheduled on node01.
- Removing the taint from the control plane enabled the "mosquito" pod to be scheduled there.
Using taints and tolerations effectively can help you control where pods are deployed and maintain a balanced and secure Kubernetes environment.
Watch Video
Watch video content