Command Palette

Search for a command to run...

Hectal
PHASE 0Beginner ~15 min· topic 5 of 5

Topic 0.5

Labels, Selectors & Annotations: How Objects Find Each Other

In one line

Labels are short key-value tags on objects (app: web, tier: backend, env: prod). Selectors pick objects by their labels, and that's how Kubernetes connects things: a Deployment finds its pods, a Service finds the pods to send traffic to, a NetworkPolicy finds which pods it applies to. Annotations are also key-value pairs, but for information tools read, not for selecting.

0/5 · 0%

Think of it like this

Coloured stickers on lunch boxes in a canteen. 'Green = vegetarian, blue = Block A'. The delivery runner doesn't need names: 'take every box with green and Block A stickers' is enough. Labels are the stickers and selectors are the instructions.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Label
A key-value tag on an object, used to group and select objects.
Selector
A query that matches objects by their labels.
Annotation
Key-value metadata for tools and people, not used for selection.
matchLabels
The selector field listing labels an object must have to match.
Recommended labels
The standard app.kubernetes.io/* labels shared by tools.

Step by step

01Labels connect the web app's objects

Tiffin's web Deployment labels its pods app: web. The Service selects app: web to route traffic. If a pod has the label, it gets traffic. There's no list of pod names anywhere.

k8s/web-deployment.yaml (labels)whole fileyaml
metadata:
  name: web
  labels:
    app.kubernetes.io/name: web
    app.kubernetes.io/part-of: tiffin
  annotations:
    tiffin.in/owner: "team-checkout@tiffin.in"
    tiffin.in/git-commit: "8f3a1c2"
spec:
  selector:
    matchLabels: { app: web }          # immutable: keep it stable
  template:
    metadata:
      labels:
        app: web
        version: "2.1.0"               # extra labels can change freely
        env: prod
Labels connect the web app's objectsdiagram
Rendering diagram…

02Selecting from the command line

Labels make kubectl queries easy: all prod pods of one app, everything that isn't a canary, or a column showing a label's value.

terminal
$ kubectl get pods -l app=web,env=prod
kubectl get pods -l 'env in (prod,staging),!canary' -L version
kubectl label pod web-6f8d9c7b54-7ktbq debug=true
── expected output ──
NAME READY STATUS RESTARTS AGE
web-6f8d9c7b54-7ktbq 1/1 Running 0 2h
web-6f8d9c7b54-vq2lm 1/1 Running 0 2h
NAME READY STATUS RESTARTS AGE VERSION
web-6f8d9c7b54-7ktbq 1/1 Running 0 2h 2.1.0
web-6f8d9c7b54-vq2lm 1/1 Running 0 2h 2.1.0
pod/web-6f8d9c7b54-7ktbq labeled

03Taking a pod out of rotation for debugging

Because the Service routes by label, removing the app label from one misbehaving pod takes it out of traffic, and the Deployment immediately creates a replacement (it no longer counts that pod). The removed pod stays alive for investigation.

terminal
$ kubectl label pod web-6f8d9c7b54-7ktbq app-
kubectl get pods -L app
── expected output ──
pod/web-6f8d9c7b54-7ktbq unlabeled
NAME READY STATUS RESTARTS AGE APP
web-6f8d9c7b54-7ktbq 1/1 Running 0 2h
web-6f8d9c7b54-vq2lm 1/1 Running 0 2h web
web-6f8d9c7b54-zt6hp 1/1 Running 0 5s web

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

A Service whose selector matches nothing

The Service selects app: tiffin-web, but the pods are labelled app: web.

terminal
$ kubectl get endpointslices -l kubernetes.io/service-name=web
curl -s -o /dev/null -w '%{http_code}\n' http://web.tiffin.svc.cluster.local # from another pod
── what you'll see ──
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
web-x7k2p IPv4 <unset> <unset> 5m
000
# curl: (7) Failed to connect: Connection refused

Myth vs fact

Myth

Kubernetes connects a Service to a Deployment by name.

Fact

There's no name link at all. Services and Deployments both find pods by labels, so labels are the real connection.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Put a version label on pods (not in the Deployment's selector). Dashboards and kubectl get pods -L version then show exactly which version each pod runs during a rollout.

Remember this

  1. 1

    Labels live in metadata.labels. Keys can have a prefix (app.kubernetes.io/name). Values are short strings. Use them for things you'll select by: app, component, environment, version, team.

  2. 2

    Equality selectors: app=web,env=prod. Set selectors: env in (prod,staging), tier notin (frontend), !canary. Use them with kubectl get -l.

  3. 3

    Selectors connect objects: a Deployment's spec.selector must match its pod template's labels, and a Service's spec.selector picks the pods that receive traffic. If labels don't match, the connection silently doesn't happen.

  4. 4

    Recommended labels: app.kubernetes.io/name, instance, version, component, part-of, managed-by. Tools like Helm and dashboards understand them.

  5. 5

    Annotations hold non-identifying data: build info, Git commit, owner contact, and configuration for controllers (nginx.ingress.kubernetes.io/rewrite-target, Prometheus scrape settings). You can't select by annotation.

  6. 6

    A Deployment's selector is immutable: you can't change it after creation, so choose stable labels for it (app: web) and put changing things (version) in extra labels.

Explain it without notes

01

Why must a Deployment's selector match its pod template labels?

02

When would you use an annotation instead of a label?

Practice

01

Label pods by environment and list only the staging ones, with their version as a column.

02

Take one pod out of a Service's traffic without deleting it, then put it back.

Trade-offs

  • ↔

    Labels give flexible, loose coupling between objects, but mismatches fail silently. Consistent naming conventions and checks (policies, linting) prevent most mistakes.

Done when you can

  • I can explain how Services and Deployments find pods.

  • I can select objects with label queries.

  • I know when to use labels vs annotations.