In this new entry, continuing with Kubernetes articles, we’ll explore how the node selector in Kubernetes works and how to apply it. This functionality is particularly helpful in environments with different nodes having varying resources.
In production environments, it’s common to have different nodes to cater to various needs. For instance, one node might prefer microservices, while another might prioritize infrastructure services, or we might need to locate pods geographically.This is where the node selector comes into play.
In a previous post we deep about node affinity,
What is Node Selector in Kubernetes?
A node selector, also known as nodeSelector
, is a field specified in the Pod specification. It’s defined as a key-value map.
The purpose of nodeSelector
, as mentioned, is to determine whether a pod can be executed on a selected node. The node must also have a matching key-value pair. This way, the pod and node match, allowing the pod to run exclusively on the selected node.
Example Application of a Node Selector
In the current environment I’m working in, we have four different nodes, and pods are assigned to nodes based on their functionality. For instance, microservices pods are assigned to one node, while infrastructure applications like Jenkins might be placed on another node with specific resources.
Let’s walk through the steps and requirements to apply a nodeSelector
to a pod.
Create a Label on a Node to Apply Node Selector
To assign a pod to a node, the first step is to create the corresponding label on the node. Let’s obtain a list of nodes:
kubectl get nodes
Once we’ve selected the node to which we want to add the label, execute the following command, kubectl label nodes <node-name> <label-key>=<label-value>, for example:
kubectl label nodes ip-190-168-140-57.ec2.internal nodegroup-type=microservices
As always, make sure the node value has a correct value. You can verify using:
kubectl describe nodes
Alternatively, check a specific node:
kubectl describe nodes ip-190-168-140-57.ec2.internal
As seen in the above code, the node is modified, and now it has a node selector to associate a pod with it.
Name: ip-190-168-140-57.ec2.internal Roles: <none> Labels: alpha.eksctl.io/cluster-name=eks-dev-cluster alpha.eksctl.io/instance-id=i-0100bdd9c9bd76460 alpha.eksctl.io/nodegroup-name=instances-stateless beta.kubernetes.io/arch=amd64 beta.kubernetes.io/instance-type=c5.2xlarge beta.kubernetes.io/os=linux failure-domain.beta.kubernetes.io/region=us-east-1 failure-domain.beta.kubernetes.io/zone=us-east-1c kubernetes.io/arch=amd64 kubernetes.io/hostname=ip-190-168-140-57.ec2.internal kubernetes.io/os=linux node.kubernetes.io/instance-type=c5.2xlarge nodegroup-instances=mixed-instances-stateless nodegroup-type=microservices topology.kubernetes.io/region=us-east-1 topology.kubernetes.io/zone=us-east-1c
Creating a NodeSelector on a Pod Associated with a Node
To associate a pod with a node, you need to assign the node’s label to the pod’s nodeSelector
.
Here’s an example of creating a pod associated with a node having the “microservices” label. Let’s say we’re deploying a service we’ve built locally:
apiVersion: v1 kind: Pod metadata: namespace: microservice-stack name: location labels: env: dev spec: containers: - name: location image: location:latest nodeSelector: nodegroup-type=microservices
Now, we can verify the localtion of our pod. To do this, use the following command. We’ll add the namespace as we’ve deployed it within a specific namespace:
kubectl get pod location -o wide -n microservice-stack
In our case, we can see that we have deployed the pod on the specific node:
sqlCopy code
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES location 1/1 Running 0 2m 10.0.2.199 ip-190-168-140-57.ec2.internal <none> <none>
Conclusion
In this article on Kubernetes Node Selector, we’ve seen a simple example and use case of when and how to apply nodeSelector
in Kubernetes. In upcoming articles, we’ll also explore the usage of nodeAffinity
, which operates based on resources.