Kubernetes labels, selectors & annotations with examples | GoLinuxCloud (2024)

Kubernetes provides two basic ways to document your infrastructure—labels and annotations. We have used labels in some of the examples in previous articles, but here I will explain the usage of labels and other related terminologies.

Topics we will cover hide

Labels

Selectors

Annotations

Assigning a label to a Deployment

Using labels to list resource objects

Using selector to list resource objects

Removing labels

Labels

  • Labels give us another level of categorization, which becomes very helpful in terms of everyday operations and management.
  • Labels are attached to Kubernetes objects and are simple key: value pairs.
  • You will see them on pods, replication controllers, replica sets, services, and so on.
  • Labels themselves and the keys/values inside of them are based on a constrained set of variables, so that queries against them can be evaluated efficiently using optimized algorithms and data structures.
  • Labels are used for organization and selection of subsets of objects, and can be added to objects at creation time and/or modified at any time during cluster operations.

Let’s use an easy example to demonstrate. Suppose you wanted to identify a pod as being part of the front-end tier of your application. You might create a label named tier and assign it a value of frontend—like so:

“labels”: {“tier”: “frontend”}

The text “tier” is the key, and the text “frontend” is the value.

Selectors

Labels are queryable — which makes them especially useful in organizing things. The mechanism for this query is a label selector. A label selector is a string that identifies which labels you are trying to match.There are currently two types of selectors: equality-based and set-based selectors.

ALSO READKubernetes sidecar example | Create multi-container Pod

Equality-based selector

An equality-based test is just a “IS/IS NOT” test. For example:

tier = frontend

will return all pods that have a label with the key “tier” and the value “frontend”. On the other hand, if we wanted to get all the pods that were not in the frontend tier, we would say:

tier != frontend

You can also combine requirements with commas like so:

tier != frontend, game = super-shooter-2

This would return all pods that were part of the game named super-shooter-2 but were not in its frontend tier.

Set-based selectors

Set-based tests, on the other hand, are of the “IN/NOT IN” variety. For example:

environment in (production, qa)tier notin (frontend, backend)partition

The first test returns pods that have the environment label and a value of either production or qa. The next test returns all the pods not in the frontend or backend tiers. Finally, the third test will return all pods that have the partition label—no matter what value it contains.

Like equality-based tests, these can also be combined with commas to perform an AND operation like so:

environment in (production, qa), tier notin (frontend, backend), partition

This test returns all pods that are in either the production or qa environment, also not in either the frontend or backend tiers, and have a partition label of some kind.

Annotations

Annotations are bits of useful information you might want to store about a pod (or cluster, node, etc.) that you will not have to query against. They are also key/value pairs and have the same rules as labels.

ALSO READHow to troubleshoot OpenStack ironic introspection

Examples of things you might put there are the pager contact, the build date, or a pointer to more information someplace else—like a URL.

Labels are used to store identifying information about a thing that you might need to query against. Annotations are used to store other arbitrary information that would be handy to have close but won’t need to be filtered or searched.

Assigning a label to a Deployment

Method-1: Assign labels while creating a new object

It is always a good idea to use YAML template from any of the existing resource object. Since we plan to create a deployment, I can use a YAML template from any of the existing template but if you don't have any existing template then you can create one using --dry-run and export the template into another YAML file:

[root@controller ~]# kubectl create deployment label-nginx-example --image=nginx --dry-run=client -o yaml > label-nginx-example.yml

So we now have a template file for a new deployment with following content:

[root@controller ~]# cat label-nginx-example.ymlapiVersion: apps/v1kind: Deploymentmetadata: creationTimestamp: null labels: app: label-nginx-example name: label-nginx-examplespec: replicas: 1 selector: matchLabels: app: label-nginx-example strategy: {} template: metadata: creationTimestamp: null labels: app: label-nginx-example spec: containers: - image: nginx name: nginx resources: {}status: {}

We can perform clean up in this file and remove some unwanted content. You can see that by default kubectl has created and assigned a label app: label-nginx-example, I will replace that and assign a new label to our deployment as app: prod.

[root@controller ~]# cat label-nginx-example.ymlapiVersion: apps/v1kind: Deploymentmetadata: labels: app: prod name: label-nginx-examplespec:  replicas: 2 selector: matchLabels: app: prod template: metadata: labels: app: prod spec: containers: - image: nginx name: nginx

Next let us create a new deployment:

[root@controller ~]# kubectl create -f label-nginx-example.ymldeployment.apps/label-nginx-example created

List the available deployments with their labels:

[root@controller ~]# kubectl get deployments --show-labelsNAME READY UP-TO-DATE AVAILABLE AGE LABELSlabel-nginx-example 2/2 2 2 3m12s app=prodnginx-deploy 2/2 2 2 22h type=dev

List the available pods with their labels:

[root@controller ~]# kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSlabel-nginx-example-5c57d87787-qjmhw 1/1 Running 0 4m36s app=prod,pod-template-hash=5c57d87787label-nginx-example-5c57d87787-vsjv5 1/1 Running 0 4m36s app=prod,pod-template-hash=5c57d87787nginx-deploy-d98cc8bdb-48ppw 1/1 Running 1 22h pod-template-hash=d98cc8bdb,type=devnginx-deploy-d98cc8bdb-nvcb5 1/1 Running 1 22h pod-template-hash=d98cc8bdb,type=dev
ALSO READKubernetes ConfigMaps usage to declare env variables

Method-2: Assign a new label to existing pod runtime as a patch

In this example we will assign new label "tier: frontend" to our existing Pods from the deployment label-nginx-example which we created in the previous example. To achieve this we need to create a spec file with the required properties:

[root@controller ~]# cat update-label.ymlspec: template: metadata: labels: tier: frontend

Next patch the deployment with this YAML file:

[root@controller ~]# kubectl patch deployment label-nginx-example --patch "$(cat update-label.yml)"deployment.apps/label-nginx-example patched

Now you can use kubectl describe to check if our label was applied to the deployment:

[root@controller ~]# kubectl describe deployment label-nginx-exampleName: label-nginx-exampleNamespace: defaultCreationTimestamp: Thu, 03 Dec 2020 11:35:15 +0530Labels: app=prodAnnotations: deployment.kubernetes.io/revision: 2Selector: app=prodReplicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailableStrategyType: RollingUpdateMinReadySeconds: 0RollingUpdateStrategy: 25% max unavailable, 25% max surgePod Template: Labels: app=prod tier=frontend...

This would apply the label to the Pod:

[root@controller ~]# kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSlabel-nginx-example-79fdbb7d49-sd82d 1/1 Running 0 8m26s app=prod,pod-template-hash=79fdbb7d49,tier=frontendlabel-nginx-example-79fdbb7d49-wf2c4 1/1 Running 0 8m18s app=prod,pod-template-hash=79fdbb7d49,tier=frontendnginx-deploy-d98cc8bdb-48ppw 1/1 Running 1 22h pod-template-hash=d98cc8bdb,type=devnginx-deploy-d98cc8bdb-nvcb5 1/1 Running 1 22h pod-template-hash=d98cc8bdb,type=dev

Method-3: Assign a new label to existing deployments runtime using kubectl

In this example we can assign a new label runtime using kubectl command to our deployment. I have another deployment nginx-deploy on my cluster, so I will assign label tier: backend to this deployment:

[root@controller ~]# kubectl label deployment nginx-deploy tier=backenddeployment.apps/nginx-deploy labeled

Verify if the label was applied successfully:

[root@controller ~]# kubectl get deployments --show-labelsNAME READY UP-TO-DATE AVAILABLE AGE LABELSlabel-nginx-example 2/2 2 2 14m app=prodnginx-deploy 2/2 2 2 22h tier=backend,type=dev

Using labels to list resource objects

Now I have already used some of these commands in previous example but let me summarise all here again for your reference.

ALSO READPerform Kubernetes Autoscaling | Horizontal Pod Autoscaler (HPA)

To list all the pods with their label details:

[root@controller ~]# kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSlabel-nginx-example-79fdbb7d49-sd82d 1/1 Running 0 8m26s app=prod,pod-template-hash=79fdbb7d49,tier=frontendlabel-nginx-example-79fdbb7d49-wf2c4 1/1 Running 0 8m18s app=prod,pod-template-hash=79fdbb7d49,tier=frontendnginx-deploy-d98cc8bdb-48ppw 1/1 Running 1 22h pod-template-hash=d98cc8bdb,type=devnginx-deploy-d98cc8bdb-nvcb5 1/1 Running 1 22h pod-template-hash=d98cc8bdb,type=dev

To list all the deployments with their label details:

[root@controller ~]# kubectl get deployments --show-labelsNAME READY UP-TO-DATE AVAILABLE AGE LABELSlabel-nginx-example 2/2 2 2 19m app=prodnginx-deploy 2/2 2 2 22h tier=backend,type=dev

To list all resources with assigned labels:

[root@controller ~]# kubectl get all --show-labelsNAME READY STATUS RESTARTS AGE LABELSpod/label-nginx-example-79fdbb7d49-sd82d 1/1 Running 0 9m8s app=prod,pod-template-hash=79fdbb7d49,tier=frontendpod/label-nginx-example-79fdbb7d49-wf2c4 1/1 Running 0 9m app=prod,pod-template-hash=79fdbb7d49,tier=frontendpod/nginx-deploy-d98cc8bdb-48ppw 1/1 Running 1 22h pod-template-hash=d98cc8bdb,type=devpod/nginx-deploy-d98cc8bdb-nvcb5 1/1 Running 1 22h pod-template-hash=d98cc8bdb,type=devNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELSservice/kubernetes ClusterIP 10.96.0.1 443/TCP 5d12h component=apiserver,provider=kubernetesNAME READY UP-TO-DATE AVAILABLE AGE LABELSdeployment.apps/label-nginx-example 2/2 2 2 19m app=proddeployment.apps/nginx-deploy 2/2 2 2 22h tier=backend,type=devNAME DESIRED CURRENT READY AGE LABELSreplicaset.apps/label-nginx-example-5c57d87787 0 0 0 19m app=prod,pod-template-hash=5c57d87787replicaset.apps/label-nginx-example-79fdbb7d49 2 2 2 9m8s app=prod,pod-template-hash=79fdbb7d49,tier=frontendreplicaset.apps/nginx-deploy-d98cc8bdb 2 2 2 22h pod-template-hash=d98cc8bdb,type=dev

To list all the deployments using type: dev label:

[root@controller ~]# kubectl get deployments -l type=devNAME READY UP-TO-DATE AVAILABLE AGEnginx-deploy 2/2 2 2 22h

To list all the pods using app: prod label:

[root@controller ~]# kubectl get pods -l app=prodNAME READY STATUS RESTARTS AGElabel-nginx-example-79fdbb7d49-sd82d 1/1 Running 0 12mlabel-nginx-example-79fdbb7d49-wf2c4 1/1 Running 0 12m

Using selector to list resource objects

In this section we will use selectors to list the deployments and pods. The pod's selector determines where the ReplicaSet is running, so in our examples we have defined selector when creating a deployment.

But to demonstrate, I will create another deployment here with two labels and use one of the label as selector:

[root@controller ~]# cat lab-nginx.ymlapiVersion: apps/v1kind: Deploymentmetadata: labels: app: dev tier: backend name: lab-nginxspec: replicas: 2 selector: matchLabels: app: dev template: metadata: labels: app: dev spec: containers: - image: nginx name: nginx

Now we will create this deployment:

[root@controller ~]# kubectl create -f lab-nginx.ymldeployment.apps/lab-nginx created

List the applied labels to the newly created pods and deployment:

[root@controller ~]# kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSlab-nginx-58f9bf94f7-df24l 0/1 ContainerCreating 0 34s app=dev,pod-template-hash=58f9bf94f7lab-nginx-58f9bf94f7-pc8zf 1/1 Running 0 34s app=dev,pod-template-hash=58f9bf94f7label-nginx-example-79fdbb7d49-sd82d 1/1 Running 0 52m app=prod,pod-template-hash=79fdbb7d49,tier=frontendlabel-nginx-example-79fdbb7d49-wf2c4 1/1 Running 0 52m app=prod,pod-template-hash=79fdbb7d49,tier=frontendnginx-deploy-d98cc8bdb-48ppw 1/1 Running 1 23h pod-template-hash=d98cc8bdb,type=devnginx-deploy-d98cc8bdb-nvcb5 1/1 Running 1 23h pod-template-hash=d98cc8bdb,type=dev[root@controller ~]# kubectl get deployments --show-labelsNAME READY UP-TO-DATE AVAILABLE AGE LABELSlab-nginx 0/2 2 0 15s app=dev,tier=backendlabel-nginx-example 2/2 2 2 62m app=prodnginx-deploy 2/2 2 2 23h tier=backend,type=dev

So, all the pods from our lab-nginx deployment has two labels but is using app=dev as the selector so we can use this to filter the list of pods:

[root@controller ~]# kubectl get pods --selector "app=dev"NAME READY STATUS RESTARTS AGElab-nginx-58f9bf94f7-df24l 1/1 Running 0 18mlab-nginx-58f9bf94f7-pc8zf 1/1 Running 0 18m

But will we get any output if we use tier: backend as the selector:

[root@controller ~]# kubectl get pods --selector "tier=backend"No resources found in default namespace.

No resources found as we are using app=dev as our selector for the pods part of lab-nginx deployment.

To list all the deployments with selector app: prod

[root@controller ~]# kubectl get deployments --selector "app=prod"NAME READY UP-TO-DATE AVAILABLE AGElabel-nginx-example 2/2 2 2 32m

In the last example we used equality-based selector to filter the available deployments, now we will use set-based selector:

[root@controller ~]# kubectl get deployments --selector "app in (prod, dev)"NAME READY UP-TO-DATE AVAILABLE AGElab-nginx 2/2 2 2 21mlabel-nginx-example 2/2 2 2 83m

Removing labels

We can also remove a label from a resource object using following syntax:

]# kubectl label <resource-type> <resource> <label-key>-

For example to remove label app: dev from pods created by lab-nginx deployment:

[root@controller ~]# kubectl label pod lab-nginx-58f9bf94f7-pc8zf app-pod/lab-nginx-58f9bf94f7-pc8zf labeled

As soon as we remove the selector label from the Pod, replicaset will create another Pod to fulfil the replica requirement of the deployment. Since lab-nginx expects two replica pods with label app=dev, another one will be created as soon as we remove label from existing Pod:

[root@controller ~]# kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSlab-nginx-58f9bf94f7-df24l 1/1 Running 0 106m app=dev,pod-template-hash=58f9bf94f7lab-nginx-58f9bf94f7-fbkc2 0/1 ContainerCreating 0 3s app=dev,pod-template-hash=58f9bf94f7lab-nginx-58f9bf94f7-pc8zf 1/1 Running 0 106m pod-template-hash=58f9bf94f7...

So as expected, you can see that as soon as I removed the app label from exiting lab-nginx Pod, a new one is getting created.

Similarly, we can also remove label from a deployment:

[root@controller ~]# kubectl get deployments --show-labelsNAME READY UP-TO-DATE AVAILABLE AGE LABELSlab-nginx 2/2 2 2 107m app=dev,tier=backendlabel-nginx-example 2/2 2 2 169m app=prodnginx-deploy 2/2 2 2 25h tier=backend,type=dev

Now we remove app label from this deployment:

[root@controller ~]# kubectl label deployment lab-nginx app-deployment.apps/lab-nginx labeled

Verify the available set of label of your deployment:

[root@controller ~]# kubectl get deployments --show-labelsNAME READY UP-TO-DATE AVAILABLE AGE LABELSlab-nginx 2/2 2 2 107m tier=backendlabel-nginx-example 2/2 2 2 170m app=prodnginx-deploy 2/2 2 2 25h tier=backend,type=dev
ALSO READBeginners guide to Kubernetes Service Account with examples

Conclusion

In this Kubernetes Tutorial we learned about the usage of labels, selector and annotation using different examples. To summarise, labels and annotation help you organize the Pods once your cluster size grows in size and scope. These are mostly used with replication controllers and replica sets in a deployment. You also learned that we can assign/modify/remove labels from different Kubernetes resource runtime.

Views: 197

Deepak Prasad

He is the founder of GoLinuxCloud and brings over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels in various domains, from development to DevOps, Networking, and Security, ensuring robust and efficient solutions for diverse projects. You can reach out to him on his LinkedIn profile or join on Facebook page.

Kubernetes labels, selectors & annotations with examples | GoLinuxCloud (2024)

References

Top Articles
Latest Posts
Article information

Author: Frankie Dare

Last Updated:

Views: 6347

Rating: 4.2 / 5 (53 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Frankie Dare

Birthday: 2000-01-27

Address: Suite 313 45115 Caridad Freeway, Port Barabaraville, MS 66713

Phone: +3769542039359

Job: Sales Manager

Hobby: Baton twirling, Stand-up comedy, Leather crafting, Rugby, tabletop games, Jigsaw puzzles, Air sports

Introduction: My name is Frankie Dare, I am a funny, beautiful, proud, fair, pleasant, cheerful, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.