nodeSelector

nodeSelector is the simplest recommended form of node selection constraint. nodeSelector is a field of PodSpec. It specifies a map of key-value pairs. For the pod to be eligible to run on a node, the node must have each of the indicated key-value pairs as labels (it can have additional labels as well). The most common usage is one key-value pair.

Attach a label to the node

Run kubectl get nodes to get the names of your cluster’s nodes.

kubectl get nodes

Output will be like


NAME                                          STATUS   ROLES    AGE    VERSION
ip-192-168-15-67.us-east-2.compute.internal   Ready    <none>   3d5h   v1.17.12-eks-7684af
ip-192-168-58-41.us-east-2.compute.internal   Ready    <none>   3d5h   v1.17.12-eks-7684af
ip-192-168-95-39.us-east-2.compute.internal   Ready    <none>   3d5h   v1.17.12-eks-7684af

We will add a new label disktype=ssd to the first node on this list.

but first, let’s confirm the label hasn’t be assign to any nodes by filtering the previous using the selector option.

kubectl get nodes --selector disktype=ssd

Output


No resources found in default namespace.

To add a label to the fist node, we can run these command

# export the first node name as a variable
export FIRST_NODE_NAME=$(kubectl get nodes -o json | jq -r '.items[0].metadata.name')

# add the label to the node
kubectl label nodes ${FIRST_NODE_NAME} disktype=ssd

Output example


node/ip-192-168-15-67.us-east-2.compute.internal labeled

We can verify that it worked by re-running the kubectl get nodes --selector command

kubectl get nodes --selector disktype=ssd

Output example


NAME                                          STATUS   ROLES    AGE    VERSION
ip-192-168-15-67.us-east-2.compute.internal   Ready    <none>   3d6h   v1.17.12-eks-7684af

Deploy a nginx pod only to the node with the new label

We will now create a simple pod creating file with the nodeSelector in the pod spec

cat <<EoF > ~/environment/pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd
EoF

Then you run

kubectl apply -f ~/environment/pod-nginx.yaml

And the Pod will get scheduled on the node that you attached the label to. You can verify that it worked by running

kubectl get pods -o wide

Sample Output


NAME    READY   STATUS              RESTARTS   AGE   IP       NODE                                          NOMINATED NODE   READINESS GATES
nginx   0/1     ContainerCreating   0          4s    <none>   ip-192-168-15-67.us-east-2.compute.internal   <none>           <none>

The NODE name should match the output of the command below

kubectl get nodes --selector disktype=ssd

Sample Output


NAME                                          STATUS   ROLES    AGE    VERSION
ip-192-168-15-67.us-east-2.compute.internal   Ready    <none>   3d6h   v1.17.12-eks-7684af