1. The Scheduler in Kubernetes
kube-scheduler is the component in Kubernetes that decides which Node a Pending Pod runs on; it is called the scheduler.
Kubernetes ships with a large number of built-in scheduling policies and also provides some advanced scheduling policies (nodeAffinity, podAffinity, and so on) for users, which is basically enough to satisfy the vast majority of business requirements.
The earlier document Labels and Selectors in Kubernetes mentioned that Labels and Selectors are very important features in Kubernetes. Labels connect Pods, Deployments, and Services, and they are also used in scheduling policies. Below we will look at how to use Labels to customize scheduling policies.
2. nodeSelector
First, look at what Labels a Node has:
| |
Let’s review the basic operations on Labels:
- Add a label
| |
- Modify a label
| |
- Delete a label
| |
When using nodeSelector, add nodeSelector to the Pod’s Spec field, which states all the Label conditions the Node must satisfy at the same time. The example below schedules the Pod onto the Node that has the kubernetes.io/hostname=node1 Label.
spec:
containers:
- ...
nodeSelector:
kubernetes.io/hostname: node1
After version 1.2, Kubernetes introduced nodeAffinity, which is functionally similar to nodeSelector; nodeSelector will be deprecated in later versions.
3. nodeAffinity
nodeAffinity is mainly used to control which Node a Pod should run on. There are two ways to schedule by affinity:
- Soft policy, satisfy if possible
- Hard policy, must satisfy
These policies are decided by Label matching, and Kubernetes provides several operators:
- In, the Label is in some list
- NotIn, the Label is not in some list
- Gt, the Label is greater than some value
- Lt, the Label is less than some value
- Exists, the Label exists
- DoesNotExist, the Label does not exist
With these operators and Labels, we can customize our own scheduling policies. Below is an official example:
| |
Add a nodeAffinity field to the Pod’s Spec to describe this.
If multiple nodeSelectorTerms are specified at the same time, the Node only needs to satisfy one of them to be schedulable. If multiple matchExpressions are specified, the Node must satisfy all of them to be schedulable.
4. podAffinity
podAffinity is similar to nodeAffinity, except that nodeAffinity describes a Pod’s selection of a Node, while podAffinity describes a Pod’s selection of a Pod.
podAffinity has an extra topologyKey (topology domain), which is equivalent to adding a dimension for choosing a Node to the Pod’s scheduling policy. First the Node’s Label must satisfy the topologyKey requirement, and then we examine whether the Labels carried by the running Pods satisfy the affinity requirement.
The example below requires the Pod’s scheduling to satisfy:
- The Node’s Label must have failure-domain.beta.kubernetes.io/zone
- The Pods running on the Node must have the Label security=S1
- Try not to schedule onto a Node whose Label has kubernetes.io/hostname and whose Pod Label has security=S2
| |
5. taints, tolerations
taints target Nodes, and tolerations target Pods. If a Node is marked with a taint, then that Node will not be scheduled to, unless the Pod is given tolerations that tolerate this taint. taints and tolerations are usually used for scheduling onto some special Nodes, such as a master, a Node with GPUs, a Node with SSDs, a Node with a lot of memory, and so on.
The format of a taint is: <key>=<value>:<effect>.
Here key and value (both may be empty) are used for tolerations matching, while effect has three values:
- PreferNoSchedule , try not to schedule
- NoSchedule , cannot schedule
- NoExecute , cannot schedule, and evict existing Pods at the same time
- Add a taint to a Node
| |
- View a Node’s taint
| |
- Remove a taint from a Node
| |
- Have a Pod tolerate a taint
In the Pod’s Spec field, add tolerations to describe the taint it tolerates. The example below happens to tolerate the taint applied above:
| |
