Scheduling
Manual Scheduling
- When you don’t specify the
nodeName
field while creating the manifest, Kubernetes automatically adds it.
- Without a Scheduler, the easiest way to schedule a pod is to simply set the nodeName field within your Pod manifest file.
apiVersion: v1 kind: Pod metadata: name: egschudling spec: containers: - image: busybox name: testsch nodeName: node01
- You can also assign the Pod to another node after creation, Kubernetes won’t let you modify the
nodeName
property of the Pod, hence, you will have to create a Binding object and send a POST request to the POD Binding API.apiVersion: v1 kind: Binding metadata: name: nginx target: apiVersion: v1 kind: Node name: node02
curl --header "Content-Type: application/json" --request POST --data '{ "apiVersion": "v1", "kind": "Binding", "metadata": { "name": "nginx" }, "target": { "apiVersion": "v1", "kind": "Node", "name": "node02" } }' http://$SERVER/api/v1/namespaces/dafault/pods/$PODNAME/binding
- When you don’t specify the
Labels and Selectors
- To make it easy to manage objects, Kubernetes uses Labels and Selectors to group and connect things together.
apiVersion: v1 kind: Pod metadata: name: nginx labels: app: App1 function: Front-end spec: containers: - name: frontend image: nginx --- apiVersion: apps/v1 kind: ReplicaSet metadata: name: simple-webapp labels: app: App1 function: Front-end annotations: buildversion: 1.34 spec: replicas: 2 selectors: matchLabels: app: App1 template: metadata: name: nginx labels: app: App1 function: Front-end spec: containers: - name: frontend image: nginx
$ kubectl get pods --selector app=App1
- While labels and selectors are used to group objects together, annotations are used to record other details for informative purposes.
- To make it easy to manage objects, Kubernetes uses Labels and Selectors to group and connect things together.
Taints and tolerations
- Taints and tolerations are mainly used to make sure that Pods are placed on the appropriate Node.
- You can taint a Node using the following command →
$
kubectl
taint
nodes
[NODE_NAME] [KEY]
=
[VALUE]
:
[TAINT-EFFECT]
- Taint effects define how nodes should react to pods that don’t tolerate it.
- NoSchedule → Instructs Kubernetes not to schedule any new pods to the node unless the pod tolerates the node.
- PreferNoSchedule → Will only schedule the Pod if there is no suitable untainted node found.
- NoExecute → Will not schedule new pods, existing pods will be evicted.
// e.g to taint and untaint a node. $ kubectl taint node node01 app=blue:NoSchedule // untaint the node by adding [-] $ kubectl taint node node01 app=blue:NoSchedule-
apiVersion: v1 kind: Pod metadata: name: myapp-prod spec: containers: - name: nginx image: nginx:latest tolerations: - key: "app" operator: "Equal" value: "blue" effect: "NoSchedule"
⇒ Taints and Tolerations do not tell the pod to go to a particular node. Instead, they tell the node to only accept pods with certain tolerations.
- Taint effects define how nodes should react to pods that don’t tolerate it.
Node Selectors
- A simple Pod scheduling feature that allows scheduling Pod onto a Node whose labels match the Node Selector labels specified by the user
- You can label a node using the following command →
$ kubectl
label
nodes <node-name>
<label-key>=<label-value>
- You can specify the appropriate node by adding the
nodeSelector
field within your Pod definition file.apiVersion: v1 kind: Pod metadata: name: testpod spec: containers: - name: mycont image: busybox nodeSelector: size: large
$ kubectl label node node01 size=large
Node affinity
- Node affinity ensures that Pods are only scheduled on particular nodes.
apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: nginx-cont image: nginx affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpression: - key: size operator: In values: - Large - Medium
- Node affinity types:
- requiredDuringSchedulingIgnoredDuringExecution
- Used when the placement of Pod is crucial, If matching node does not exist the Pod will not be schedule.
- preferredDuringSchedulingIgnoredDuringExecution
- Used when the placement of Pod not as important as running the workloa, It simply ignores the node affinity rules and place the Pod on any available node.
⇒
IgnoredDuringExecution
means that if the node labels change after Kubernetes schedules the Pod, the Pod continues to run. - requiredDuringSchedulingIgnoredDuringExecution
- Operators:
Operator Behavior In The label value is present in the supplied set of strings NotIn The label value is not present in the supplied set of strings Exists A label with this key exists on the object DoesNotExist No label with this key exists on the object Gt (nodeAffinity only) The supplied value will be parsed as an integer, and that integer is less than the integer that results from parsing the value of a label named by this selector Lt (nodeAffinity only) The supplied value will be parsed as an integer, and that integer is greater than the integer that results from parsing the value of a label named by this selector
- Node affinity ensures that Pods are only scheduled on particular nodes.
DaemonSets
- DaemonSets ensures that one copy of a Pod is present and running in all nodes within the cluster. and when a node is removed the Pod is automatically removed too. good e.g. of a DaemonSet is kube-proxy.
## DaemonSet Definition file apiVersion: v1 kind: DaemonSet metadata: name: monitoring-daemon spec: template: metadata: labels: app: monitoring-agent selectors: matchLabels: app: monitoring-agent containers: - name: monitoring-agent-container image: monitoring-agent:latest
Static Pods
- Statics Pods are a type of pod that is not managed via the Kube-API server, instead, it is directly bound to the Kubelet agent on the node.
- Note that with the presence of the API server, the static pods running on a node are visible on the API server with the format
<container-name>-<node-name>
but cannot be controlled by the API server.
- It is important to note that Kubelet can manage the PODS on its own, one requirement is to have a container engine to run the containers. Suppose there is no API server to send the instructions. In that case, you can configure Kubelet to read the POD definitions from a directory on the server designated to store information about Pods. Kubelet will periodically check the directory for files, read them, create them on the host, and eventually ensure they stay alive, Kubelet will also delete the pods once the file is removed.
- You can store the Pods manifest in any Dir, make sure you pass the path to that folder as an option while running the Kubelet.service
--pod-manifest-path=/etc/Kubernetes/manifests
.Another way to configure this is by providing another config file using the
--config
option and defining the Dir path as a static pod path in that filestaticPodPath=/etc/kubernetes/manifests
.
- Once the static pods are created you can check them using docker CLI.
⇒ You can use Static Pods to deploy the control plane components as Pods on the node.
Multiple Schedulers
- Kubernetes allows you to create custom schedulers and use them as the default scheduler or an additional scheduler in the K8S cluster. That way you can instruct Kubernetes to use a specific scheduler when creating the POD.
$ cat /etc/kubernetes/manifests/my-custom-kube-scheduler.yaml apiVersion: v1 kind: Pod metadata: name: kube-scheduler namespace: kube-system spec: containers: - command: - kube-scheduler - --address=127.0.0.127 - --kubeconfig=/etc/kubernetes/scheduler.--kubeconfig - --leader-elect=true - --scheduler-name=my-custom-kube-scheduler image: k8s.gcr.io/kube-scheduler-amd64:v1:18.6 name: kube-scheduler
- Note that if you have multiple copies of the scheduler running on different master nodes, you can set the
leader-elect
option totrue
if you want only one copy of the same scheduler can be active at a time.false
in cases where you don’t have multiple masters.
- When creating the POD you can specify the scheduler service you want to use.
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx-container image: nginx schedulerName: my-custom-kube-scheduler # to verify use the command $ kubectl get events
⇒ Is important to note that if the scheduler is not configured correctly, then the Pod will continue to remain in Pending state.
- Kubernetes allows you to create custom schedulers and use them as the default scheduler or an additional scheduler in the K8S cluster. That way you can instruct Kubernetes to use a specific scheduler when creating the POD.