Analogy:
A person want to repel bugs. A person use a taint in himself to avoid those bugs that are intolerant to that taint. There are, though, some bugs that are tolerant to that taint and will be able to land on the person.
Now, assume the Node is the person, and the pods are the bugs. Taints are applied to Nodes to prevent certain pods from being instantiated in the tainted Node. But you can also make a Pod tolerant to certain taints.
Taints are set on Nodes and Toleration are set on Pods
How to apply a taint to a node:
kubectl taint nodes ${nodeName} ${key}=${value}:${taintEffect}
# ${taintEffect}: determines what happens to Pods
# that do not tolerate the taint
# - NoSchedule - intolerant pod's won't be scheduled
# - PreferNoSchedule - prefer to schedule in another Node
# - NoExecute - won't schedule and finish existing ones
# Example:
kubectl taint nodes node1 app=blue:NoSchedule
How to apply a toleration to a pod:
# pod's spec
# NOTE: the values need "double quotes"
tolerations:
- key: ${key}
operator: ${operator}
value: ${value}
effect: ${effect}
Example:
# applying a toleration to the following taint
# kubectl taint nodes node1 app=blue:NoSchedule
# pod's spec
tolerations:
- key: "app"
operator: "Equal"
value: "blue"
effect: "NoSchedule"
Note: taint-toleration technique does not guarantee that a tolerant Pod will be instantiated in the tainted Node. The feature for such usecase is called Node Affinity.
Interesting info: The Scheduler prevent pods from being instantiated in the Master Node using a taint.