You’ve most likely stumbled on Kubernetes labels while writing deployment manifests. What are they for and how to use them? As always we’ll see a practical demo to answer these questions. Keep reading to find out more.
Introduction
Previously we have seen that Kubernetes Namespaces allow to logically group Kubernetes resources. Today we’ll see another way to organize resources – Kubernetes labels.
In short, Kubernetes labels allow to mark certain API objects. This in turn allows you to search for them easily. Kubernetes internally uses labels as well. For example, Kubernetes controllers manage the desired state of only specific pods, labeled ones. Similarly, Kubernetes Services will forward requests to labeled pods only.
You can even influence Kubernetes scheduling decisions by labeling Kubernetes nodes and instructing pods to run there.
Let’s see a Kubernetes labels demo in order to better understand what we’ve just discussed.
Demo Prerequisites
I assume you have Kubernetes cluster. If you don’t, install on your machine minikube and kubectl.
Start Kubernetes cluster using minikube start --nodes 2 -p multinode-demo.
If you prefer, you can also repeat this demo on a managed Kubernetes cluster. Check out how easy it is to create Kubernetes Cluster on Linode. Get 100$ credit on Linode using this link. Linode is a cloud service provider recently purchased by Akamai. With this purchase, Akamai became a competitor in the cloud providers market.
Kubernetes labels demo
Let’s create dedicated Kubernetes namespace for our demo and set current context to use it:
kubectl create ns demo
kubectl config set-context --current --namespace=demo
Unless you had such namespace before, there should be no resources in it:
kubectl get all
No resources found in demo namespace.
Next, create nginx deployment:
$kubectl create deploy nginx --image=nginx:1.13.2 --replicas=3
deployment.apps/nginx created
Where do labels fit it?
$ kubectl get all --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod/nginx-6d67674bb5-ks4hp 1/1 Running 0 2m41s app=nginx,pod-template-hash=6d67674bb5
pod/nginx-6d67674bb5-lql8z 1/1 Running 0 2m41s app=nginx,pod-template-hash=6d67674bb5
pod/nginx-6d67674bb5-xkxvg 1/1 Running 0 2m41s app=nginx,pod-template-hash=6d67674bb5
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/nginx 3/3 3 3 2m41s app=nginx
NAME DESIRED CURRENT READY AGE LABELS
replicaset.apps/nginx-6d67674bb5 3 3 3 2m41s app=nginx,pod-template-hash=6d67674bb5
You can see above that after we created a deployment few objects were created. nginx deployment, its corresponding replica set and pods – all have got labels.
Let’s create another nginx deployment:
$ kubectl create deploy nginx2 --image=nginx:1.13.2 --replicas=2
deployment.apps/nginx2 created
Labels allow to filter pods belonging only to specific deployment:
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-6d67674bb5-ks4hp 1/1 Running 0 16m
nginx-6d67674bb5-lql8z 1/1 Running 0 16m
nginx-6d67674bb5-xkxvg 1/1 Running 0 16m
Note that Kubernetes deployment uses selectors to select its pods.
kubectl get deployments.apps nginx -o jsonpath='{.spec.selector}'
{"matchLabels":{"app":"nginx"}}
Let’s delete the nginx2 deployment in order to avoid confusion using kubectl delete deployments.apps nginx2.
Use Kubernetes labels for debugging
In addition, we can use labels for debugging. Let’s label one of the pods with app=debug label.
kubectl label pod/nginx-557f57675f-d2t8s app=debug --overwrite
pod/nginx-557f57675f-d2t8s labeled
Let’s see now how many pods we have in nginx deployment.
$ kubectl get all --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod/nginx-6d67674bb5-2mqnc 1/1 Running 0 8m20s app=debug,pod-template-hash=6d67674bb5
pod/nginx-6d67674bb5-6pnpf 1/1 Running 0 8m19s app=nginx,pod-template-hash=6d67674bb5
pod/nginx-6d67674bb5-9r5td 1/1 Running 0 5s app=nginx,pod-template-hash=6d67674bb5
pod/nginx-6d67674bb5-lpgdx 1/1 Running 0 8m20s app=nginx,pod-template-hash=6d67674bb5
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/nginx 3/3 3 3 25h app=nginx
NAME DESIRED CURRENT READY AGE LABELS
replicaset.apps/nginx-6d67674bb5 3 3 3 25h app=nginx,pod-template-hash=6d67674bb5
Interestingly, we see 4 nginx pods running while expecting only 3. Was our expectation correct? No, because the desired state of nginx deployment is 3 replicas. That’s why, nginx replica set controller has spun up a new nginx pod with label app=nginx instead of the one we labeled for debugging with app=debug.
Let’s now expose the deployment as Kubernetes service.
$kubectl expose deployment/nginx --port 8090 --target-port 80
service/nginx exposed
$kubectl get service nginx --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
nginx ClusterIP 10.97.185.55 <none> 8090/TCP 2m45s app=nginx
As you can see the service has the same label app=nginx as the pods. Of course, it uses the same selector {"app":"nginx"} as the deployment.
$kubectl get service nginx -o jsonpath='{.spec.selector}'
{"app":"nginx"}
Note, that the pod labeled for debugging won’t get the traffic directed at the service.
Suppose we finished to debug. Let’s now get the pod back into service.
$ kubectl label pod/nginx-6d67674bb5-2mqnc app=nginx --overwrite
pod/nginx-6d67674bb5-2mqnc labeled
We can see now that there are only 3 nginx pods as expected.
$ kubectl get all --show-labels -l app=nginx
NAME READY STATUS RESTARTS AGE LABELS
pod/nginx-6d67674bb5-2mqnc 1/1 Running 0 28m app=nginx,pod-template-hash=6d67674bb5
pod/nginx-6d67674bb5-9r5td 1/1 Running 0 20m app=nginx,pod-template-hash=6d67674bb5
pod/nginx-6d67674bb5-lpgdx 1/1 Running 0 28m app=nginx,pod-template-hash=6d67674bb5
Influence scheduling decisions using Kubernetes labels
Let’s now see another great use of labels – control of scheduling decisions. For that purpose, we’ll label Kubernetes node and force nginx pods to be scheduled to this specific node.
However, first let’s see the nodes the pods run on:
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-6d67674bb5-2mqnc 1/1 Running 0 47m 10.244.0.8 multinode-demo <none> <none>
nginx-6d67674bb5-9r5td 1/1 Running 0 39m 10.244.1.4 multinode-demo-m02 <none> <none>
nginx-6d67674bb5-lpgdx 1/1 Running 0 47m 10.244.0.11 multinode-demo <none> <none>
Next, let’s label one of the nodes where nginx should run:
$ kubectl label node multinode-demo app=nginx
node/multinode-demo labeled
It’s not enough. We should add nodeSelector to nginx deployment pod template spec.
Let’s do that imperatively for demo purposes:
$ kubectl edit deployments.apps nginx
Your system text editor should open. Let’s add the below block to deployment’s pod template spec and save.
nodeSelector:
app: nginx
You should see deployment.apps/nginx edited output.
Next, we’ll watch what happens:
$ kubectl get pod -o wide -w
Eventually, all nginx pods should reach their new desired state, e.g. be placed on multinode-demo node:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-67fc9bd7c9-qctb4 1/1 Running 0 5m4s 10.244.0.13 multinode-demo <none> <none>
nginx-67fc9bd7c9-r6kzp 1/1 Running 0 5m2s 10.244.0.14 multinode-demo <none> <none>
nginx-67fc9bd7c9-s8ft7 1/1 Running 0 4m59s 10.244.0.15 multinode-demo <none> <none>
To abide by configuration as code principles, one should declare Kubernetes Deployments using yaml and put nodeSelector constraint there.
You may rightfully ask, what are pod-template-hash=67fc9bd7c9 labels in replicaSets and pods. Don’t worry, we’ll cover their roles in future posts when we explore Kubernetes controllers.
Finally let’s leave our minikube cluster tidy by simply removing demo namespace. It will remove all the resources we created throughout the demo.
$ kubectl delete ns demo
namespace "demo" deleted
Summary
That’s it about Kubernetes labels. As always, feel free to share and comment.
- Become a Certified Kubernetes Administrator (CKA)!
- Become a Certified Kubernetes Application Developer (CKAD)!
- BUNDLE KUBERNETES FUNDAMENTALS & CKA CERTIFICATION (COURSE & CERTIFICATION) FOR THE BEST DEAL! $499 ONLY!
Watch recommended Kubernetes courses on Pluralsight:
Sign up using this link to get exclusive discounts like 50% off your first month or 15% off an annual subscription)
Read recommended Kubernetes books on Amazon:
