Kubernetes Scheduler

How does Kubernetes schedule a pod on a node?- Using a kube-scheduler component.

Let's see how the scheduler schedules the pods in the cluster. The scheduler goes through all the pods and takes those pods which do not have the NodeName field. It then identifies the right node for a pod by running a scheduling algorithm and schedules the pod on a node by setting the NodeName property by creating a binding object.

Manual Scheduling

An answer to this is that in every pod manifest yaml file, there is a NodeName field, which is by default not set, but if you want, you can manually set NodeName for the pod at the time of pod creation but Kubernetes automatically set it for you.

But if you want to bind a node to an existing pod then create a binding object and send a post request to the pod binding API.

# Pod-binding object yaml file 
apiVersion: v1
Kind: Binding
metadata: 
  name: nginx
target:
  apiVersion: v1 
  kind: Node
  Name: node02

# pod object creation yaml file
apiVersion: v1
Kind: Pod
metadata: 
  name: nginx
  labels: 
    name: nginx
spec:
  containers:
    - name: nginx
      image: nginx
      port: 
        - containerPort: 8080

# send binding request to pod API using json data
curl --header "Content-Type:application/json" --request POST --data '{"apiVersion":"v1", "kind":"Binding", "metadata": ...}' http://$SERVER/api/v1/namespaces/default/pods/$PODNAME/binding/

Taints and Tolerations

Mater is also a node then why does the scheduler not schedule any pod on the master node? That's because of Taints and Toleration mechanism.

# to see the taint used in master node with NoSchdule and this is how schedueler not able to schduele any pod on the master node.
kubectl describe node kubemaster | grep Taint

However, the best practice is not to deploy any pod on the master node.

What are Taints and Tolerances? How can you restrict what pods are placed on what nodes?
Taints and Tolerances are to restrict nodes from accepting certain pods. Taints are set on nodes and tolerances are set on pods.


Node Selector

Using the NodeSelctor property we can limit the pod deployment to a specific types of node.

For simple node selection for a pod, NodeSelctor does the job perfectly but if there are some complex conditions like pod should not deploy to a specific label of a node or having some more complex conditions. Then Node Affinity comes into the picture.


Node Affinity

It ensures pods are hosted on a specific node.

We see in previous examples that Node does not guarantee that pod will always deploy on that node, but this can be easily done with Node Selector. If there are some complex condition combinations of OR, AND, NOT then we will use Node Affinity. It provides us with advanced features to limit pod hosts on a specific node.

Suppose we want to place a pad on those nodes which have been labeled as Large or Medium and not Small.

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: size
            operator: In
            values:
            - Large
            - Medium
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: size
            operator: NotIn
            values:
            - Small
  containers:
  - name: with-node-affinity
    image: registry.k8s.io/pause:2.0

Taints /Tolerations and Node Affinity

Both can be combined to achieve the task - dedicated nodes for specific pods.

We first use Taints/Tolerations to prevent other pods from being placed on Nodes but this does not guarantee always so second you can use Node Affinity to prevent pods from being placed on the nodes.


Resource Limits

By default, Kuberenetes set some resource limits

ResourceCPUMemory
container within a pod
(Minimum configuration required)0.5256Mi
container
(Limit is set)1512Mi

You can change the default limits in yaml file under the label of the resource for pod usage.

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    type: front-end
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
      containerPort: 8080
    resources:
      requests:
        memory: "1Gi"
        cpu: "1"

For more reference, you can go through these links:

https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/


Daemon Sets

Daemon Sets are like ReplicaSet, deploying multiple instances of a pod. But Daemon Set ensures that one copy of your pod always runs on each node in the cluster.

For more details check my blog: https://hashnode.com/edit/clgxw2zwe000c09mm57ch186l


Static Pods

Kubernetes kubelet can host pods without any help from control plane components and those pods are called static pods. Kubelet also maintains pods, that have the capabilities of auto-healing and auto-scaling.

This concept is useful for deploying control plane components as static pods.


Multi Scheduler

You can create your custom scheduler in the Kubernetes Cluster. While creating a pod you can mention schedulerName in the yaml configuration file.
This we will see in the next blog.

Stay tuned and keep learning :)