Agentic AI with Java: Live Cohort
KubernetesNamespaces, Labels & Deployments

Labels and Selectors in Kubernetes

Learn how labels tag Kubernetes objects and how selectors find them, filter pods with kubectl -l, add labels on the fly, and see why Services, ReplicaSets and Deployments all depend on them.

Imagine a cluster running 300 pods. Someone asks: "show me only the frontend pods in the dev environment". Or a Service needs to know which of those 300 pods should receive its traffic. Pod names are random and IPs change, so neither can be used. Kubernetes answers both questions the same way, with labels and selectors.

We have already used them. The webapp pod had the label app: telusko-webapp, and every Service we created had selector: app: telusko-webapp. Before we reach ReplicaSets and Deployments, which rely on them even more, let us look at them properly.

Labels: tags on objects

A label is a key-value pair attached to a Kubernetes object, in metadata.labels. Think of it like a tag on a photo or a post: it does not change what the object is, it just makes it easy to find and group.

  • An object can have many labels
  • Many objects can share the same label
  • Labels are meant for identifying and selecting. Kubernetes itself does not attach any meaning to app or env; the meaning is whatever your team agrees

Common keys teams use:

KeyExample valuesAnswers the question
apptelusko-webapp, paymentWhich application is this?
envdev, test, prodWhich environment?
tierfrontend, backend, dbWhich layer?
teampayments, platformWho owns it?
versionv1, v2Which release?

Kubernetes also documents a set of recommended keys with a prefix, such as app.kubernetes.io/name and app.kubernetes.io/version, which tools like Helm use. Short keys like app are perfectly fine while learning.

Label rules: keys and values are up to 63 characters, start and end with a letter or number, and may contain -, _ and .. A key may have an optional DNS prefix such as app.kubernetes.io/.

Selectors: searches over labels

A selector is a search condition. It says "every object whose labels match this". Selectors appear in two places:

  1. In kubectl, with -l (or --selector), so that you can filter what you see
  2. Inside other objects, so that a Service, ReplicaSet, Deployment or DaemonSet knows which pods are "its" pods
A Service with selector app=webapp selects pod 1 and pod 2, which have app=webapp, and ignores pod 3, which has app=payment

A pod matches a selector when it has all the key-value pairs in the selector. Extra labels on the pod do not matter. So pod 1 (app=webapp, env=dev) and pod 2 (app=webapp, env=prod) both match app=webapp, and pod 3 does not.

Hands-on: a pod with two labels

vi label.yml
label.yml
apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: telusko-webapp
    env: dev
spec:
  containers:
    - name: webapp-container
      image: nginx
kubectl apply -f label.yml
kubectl get pods

Show the labels

kubectl get pods --show-labels
NAME     READY   STATUS    RESTARTS   AGE   LABELS
webapp   1/1     Running   0          44s   app=telusko-webapp,env=dev

Filter by label

kubectl get pods -l app=telusko-webapp
kubectl get pods -l env=dev
NAME     READY   STATUS    RESTARTS   AGE
webapp   1/1     Running   0          7m21s

With one pod the filter looks pointless. With hundreds of pods across teams, it is how you find anything.

More selector forms

kubectl -l understands two styles:

SelectorMatches pods where
-l app=telusko-webappapp equals telusko-webapp
-l env!=prodenv is not prod (or there is no env label)
-l app=telusko-webapp,env=devBoth conditions are true (comma means AND)
-l 'env in (dev,test)'env is dev or test
-l 'env notin (prod)'env is anything except prod
-l teamThe team label exists, any value
-l '!team'There is no team label

The first three are equality-based, the rest are set-based. Quote set-based selectors so the shell does not misread the brackets.

You can also show labels as columns:

kubectl get pods -L app,env

Add, change and remove labels without editing YAML

kubectl label pod webapp team=platform           # add
kubectl label pod webapp env=test --overwrite    # change
kubectl label pod webapp team-                   # remove (note the trailing dash)

This is handy for experiments, but remember that the YAML file is the source of truth. The next kubectl apply of the file may reset what you changed by hand.

Where selectors are used inside Kubernetes

ObjectSelector fieldWhat it selects
Servicespec.selector (plain map)Pods that receive the traffic
ReplicaSetspec.selector.matchLabels / matchExpressionsPods it counts and keeps alive
Deploymentspec.selector.matchLabelsPods belonging to the Deployment
DaemonSetspec.selector.matchLabelsPods it runs on each node
NetworkPolicypodSelectorPods the policy applies to

ReplicaSets and Deployments use matchLabels, a slightly more structured form, and also accept set-based matchExpressions. You will write them in the next lessons.

A selector that matches too much

Selectors are powerful in both directions. If a Service selects only env=dev, it will happily send traffic to every dev pod, including your database. Use a combination that uniquely identifies the app, such as app plus tier, and keep labels consistent across your manifests.

Clean up

kubectl delete -f label.yml

If you are finished for the day, delete the cluster: eksctl delete cluster --name telusko-learning --region ap-south-1 --wait.

Try It Yourself

  1. Create three pods: pod1 with app=webapp,env=dev, pod2 with app=webapp,env=prod, and pod3 with app=payment,env=dev. Use kubectl run pod1 --image=nginx --labels=app=webapp,env=dev to save typing.
  2. Predict, then check, the output of kubectl get pods -l app=webapp, -l env=dev, -l 'env in (dev,prod),app=payment' and -l env!=prod.
  3. Create a ClusterIP Service with selector app: webapp and check its Endpoints. Which pod IPs appear?
  4. Remove the app label from pod2 with kubectl label pod pod2 app- and check the Service endpoints again.

Official references


Written By: Shramik Masti

How is this guide?

Last updated on