Hello everyone! Okay since last article we’ve discuss some label and selector also service as a networking in Kubernetes. Now in this attempt we’re going to discuss Manual Scheduling, Taint & Toleration, Node Affinity and Resource Limit. It’s going to be more advance topic, and it takes time to understand it. Don’t give up to understand the concept, keep the learning up before you became a Kubernetes Administrator.
Let’s go !
1. Manual Scheduling
There are different ways to manually schedule a pod on a node, without the built in scheduler pod.
How scheduling works
Scheduler will inspect each node to check the nodeName field (assign automatically):
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 8080 nodeName: node02
It then identifies the pod that doesn’t have a nodeName to became a candidate for which node that this pod should be by running scheduling algorithm. After being identified, it will fill the void value on a nodeName and then create a binding object. Here’s the example of binding manifest file look like:
apiVersion: v1 kind: Binding metadata: name: nginx target: apiVersion: v1 kind: Node name: node02
And then send a post request to the pods binding API with the data set to the binding object in a JSON format:
curl --header "Content-Type:application/json" --request POST --data http://$SERVER/api/v1/namespaces/default/pods/$PODNAME/binding/
What happen if there is no scheduler?
The pod that you create will launch with a pending status. And to resolve that you just simply need to fill nodeName manually when at the creation time, not when the pod is already running, because Kubernetes won’t allow that.
2. Taint & Toleration
So simply taint is a rule that set to the node and toleration is a rule-tolerance that set to the pod.
How it really look like?
How to configure taints and tolerations?
Taints – Node
kubectl taint nodes node-name key=value:taint-effect
NoSchedule | PreferNoSchedule | NoExecute
taint-effect means What happens to PODs that do not tolerate this taint?
Here’s how to make node1 taint to some rule:
kubectl taint nodes node1 app=myapp:NoExecute
Then the pod who stay after node is being tainted, will be killed.
Tolerations – Pods
For instance here use the manifest file to configure it based on example above. Like:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx tolerations: - key: "app" operator: "Equal" value: "myapp" effect: "NoExecute"
💡 Make the tolerations on the manifest file based on taint key value and effect.
Use Case on Master Node
Master node isn’t allowing any pod to deploy there, it use taints and tolerations concept. Use this command to check:
kubectl describe node kubemaster | grep Taint
💡 You can untainted with addition “-” at the end of your command. The command is same as you tainted a node.
3. Node Selector & Node Affinity
Node can be labeled and selected with node selector. So the pod can be assign into the right node according to the workload.
How to label and select a node?
For instance her give the node a label first
kubectl label nodes node01 performance=high, then select it under spec field.
... nodeSelector: performance: high ...
But it has a limitation if we just use node selector, not every case can get in. Like OR || NOT case operation.
Here’s how to configure it in file, Affinity location is under spec field. If in deployment file is under template field.
... affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: size operator: In values: - Large - Medium
It means the pod will assign into node that large OR medium, because it use In operator. There are exception operator like Not In, also other operator like Exists, etc.
What if Node Affinity can’t match a node with the given expression?
There are types of node affinity. We’ll classified it based on pod’s life cycle:
- If During Scheduling = Required → Apply Node Affinities Rule in the first place → Not Match with given expression → Pod are not scheduled → for important pod.
- If During Scheduling = Preferred → Apply Node Affinities Rule in the first place → Not Match with given expression → Put the pod anywhere → less important pod.
- If During Execution = Ignored → Pod continue to run → changes won’t impact pod.
- If During Execution = Required → Pod will be terminated → changes will impact pod.
Combining Taint & Toleration with Node Affinity
In order to make each pod goes to the node that we want, we put the label to each node and use node affinity. Then to prevent other pod to get in to our node, we use taint and toleration.
4. Resource Request & Limit
Some set of rules to limit or request your node or pod resource. This is very important in production, because you won’t let a pod is built without a resource limit or request. So here’s how to configure it under the manifest file :
... spec: containers: - name: ... resources: requests: memory: "1Gi" cpu: 1
... spec: containers: - name: ... resources: requests: memory: "1Gi" cpu: 1 limits: memory: :"2Gi" cpu: 2
If the pod exceeding the limits, then it’ll be terminated.
How to change default resources?
“When a pod is created the containers are assigned a default CPU request of 0.5 and memory of 256Mi”.
For the POD to pick up those defaults you must have first set those as default values for request and limit by creating a Limit Range in that namespace.
apiVersion: v1 kind: LimitRange metadata: name: mem-limit-range spec: limits: - default: memory: 512Mi defaultRequest: memory: 256Mi type: Container
apiVersion: v1 kind: LimitRange metadata: name: cpu-limit-range spec: limits: - default: memory: 1 defaultRequest: memory: 0.5 type: Container
OOMKilled indicates that it is failing because the pod ran out of memory. Identify the memory limit set on the POD.
I hope you guys can understand the concept. I suggest if you are haven’t attempt the hands-on, you need to immediately do it. Because soon you’ll be understand it while you’re doing it. You can read more on :
Okay that’s all for now. See you!