In Kubernetes, scheduling means how to make a placement decision. A Kubernetes scheduler watches a newly created pod and finds the best node of that pod.
Node Selector
Node Selector (.spec.nodeSelector) is the simplest way to assign pods to nodes.
Here is what you can do.
Add a label to a node.
# list of nodes
kubectl get nodes --show-labels
# add a label to a node
kubectl label node {node-name} key1=value1
# check the labels of nodes
kubectl get nodes --show-labels
Create a pod with a nodeSelector.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeSelector:
key1: value1
# create a pod
kubectl apply -f pod.yaml
# verify the pod
kubectl get pods -o=wide
Node Name
Another way to assign a pod to a node is by using the node name.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodename: {node-name}
containers:
- name: nginx
image: nginx
Node Affinity
Node affinity (.spec.affinity.nodeAffinity) is a property of a pod that attracts it to a set of nodes.
- requiredDuringSchedulingIgnoredDuringExecution
- Hard rule
- The scheduler can’t schedule the pod unless the rule is met.
- This functions like nodeSelector, but with a more expressive syntax.
- preferredDuringSchedulingIgnoredDuringExecution
- Soft or preferred rule.
- The scheduler tries to find a node that meets the rule. If a matching node is not available, the scheduler still schedules the pod.
- You can specify a weight between 1 and 100.
- requiredDuringSchedulingRequiredDuringExecution
- Proposed for the future release
[Note] IgnoredDuringExecution means that if the node labels change after Kubernetes schedules the pod, the pod continues to run.
Operators
- In
- NotIn
- Exists
- DoesNotExist
Add a label to a node.
# list of nodes
kubectl get nodes --show-labels
# add a label to a node
kubectl label node {node-name} key1=value1
# check the labels of nodes
kubectl get nodes --show-labels
Create a pod with node affinity.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: key1
operator: In
values:
- value1
containers:
- name: nginx
image: nginx
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: key1
operator: Not In
values:
- value1
containers:
- name: nginx
image: nginx
# create a pod
kubectl apply -f pod.yaml
# verify the pod
kubectl get pods -o=wide
Taints and Tolerations
Unlike node affinity, taints is a property of a node that repels a set of pods. Tolerations are applied to pods. Tolerations allow the scheduler to schedule pods with matching taints.
Taints and tolerations work together to ensure that pods are not scheduled onto inappropriate nodes.
- Taints: node
- Tolerations: pod
There are 3 types of effects:
- NoSchedule: A new pod with no toleration will not be scheduled on the node. But running pod is OK.
- PreferNoSchedule: A new pod with no toleration will not be scheduled on the node if possible, but it is not guaranteed.
- NoExecute: A running pod with no toleration will be evicted, and a new pod with no toleration will not be scheduled as well.
Here is how they work.
Add a taint to a node.
# list of nodes
kubectl get nodes --show-labels
# add a taint
kubectl taint node {node-name} key1=value1:NoSchedule
# remove a taint if you want
kubectl taint node {node-name} key1=value1:NoSchedule-
# check the taints
kubectl describe node {node-name}
kubectl describe node {node-name} | grep Taints
Specify a toleration in the pod spec (.spec.tolerations)
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
tolerations:
- key: "key1"
operator: "Exists"
effect: "NoSchedule"
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
Create a pod
# create a pod
kubectl apply -f pod.yaml
# verify the pod
kubectl get pods -o=wide