Kubernetes Node Selectors
In this article we will dive into node selectors in Kubernetes.
Let us start with a simple example:
You have a three node cluster, of which two are smaller nodes with lower hardware resources and one of them is a larger node configured with higher resources.
You have different kinds of workloads running in your cluster and you would like to dedicate the data processing workloads that require higher horsepower to the larger node as that is the only node that will not run out of resources in case the job demands extra resources.
However, in the current default setup, any pods can go to any nodes.
To solve this, we can set a limitation on the pods so that they only run on particular nodes.
There are two ways of achieving this:
- Node Selectors the simple way.
- Node affinity more complex and powerful.
Node selectors is the simple and easier method. For this we look at the pod definition file:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: data-processor
image: data-processor
This file has a simple definition to create a pod with a data processing image.
To limit this pod to run on the the larger node we add a new property called Node selector to the spec section and specify the size as large.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: data-processor
image: data-processor
# New
nodeSelector:
size: Large
But wait a minute. Where did the size large come from and how does Kubernetes know which is the large node!
The key value pair of size and large are in fact labels assigned to the nodes, the scheduler uses these labels to match and identify the right node to place the pods on. You must have first labelled your nodes prior to creating this pod. I'm an inline-style link with title
So let us go back and see how we can label the nodes.
Node Labelling
To label a node use the following command structure:
kubectl label nodes
=
In our example, the command and would be:
kubeclt label nodes node-1 size=Large
Now that we have labeled the node we can go back to pod definition file, this time with the node selector set to a size of large.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: data-processor
image: data-processor
nodeSelector:
size: Large
When the pod is now created it is placed on Node 1 as desired.
Note: that selectors served our purpose but it has limitations.
We used a single label and selector to achieve our goal here. But what if our requirement is much more complex?
For example, what if we wanted to place a pod on any large or medium sized node?
Or what if we wanted to place the pod on any nodes that are not small?
You cannot achieve this using Node selectors. For this, node affinity and anti affinity features were introduced.