Kubernetes Labels and Selectors

A busy cluster holds hundreds of objects: pods, services, deployments, and more. Labels give every object a set of sticky notes, and selectors let you pick objects by reading those notes. Almost every Kubernetes feature depends on this pairing, so a clear grasp of it makes later topics much easier.

What Labels Are

A label is a key and value pair attached to an object. Think of a library where every book carries colored stickers: one color for genre, one for floor number, one for language. Librarians never memorize book locations. They ask for "all blue-sticker books on floor two" and the system finds them.

Kubernetes works the same way. You attach labels such as app: shop or tier: frontend to a pod. Other objects read those labels to decide which pods belong to them.

Label Rules

  • A key has an optional prefix and a name, separated by a slash. Example: example.com/team.
  • The name part holds up to 63 characters.
  • A value holds up to 63 characters and may be empty.
  • Keys and values start and end with a letter or digit. Dashes, underscores, and dots may appear in the middle.
  • One object can carry many labels, but each key appears once per object.

Adding Labels in a Manifest

Labels live under metadata.labels.

apiVersion: v1
kind: Pod
metadata:
  name: cart-pod
  labels:
    app: shop
    tier: backend
    env: production
spec:
  containers:
  - name: cart
    image: nginx:1.27

Diagram: Labels on Pods

Four pods carry different labels. Each box shows what the pod announces to the cluster.

┌──────────────────────┐   ┌──────────────────────┐
│ Pod A                │   │ Pod B                │
│ app=shop             │   │ app=shop             │
│ tier=frontend        │   │ tier=backend         │
│ env=production       │   │ env=production       │
└──────────────────────┘   └──────────────────────┘
┌──────────────────────┐   ┌──────────────────────┐
│ Pod C                │   │ Pod D                │
│ app=shop             │   │ app=blog             │
│ tier=frontend        │   │ tier=frontend        │
│ env=staging          │   │ env=production       │
└──────────────────────┘   └──────────────────────┘

The query app=shop,env=production returns Pod A and Pod B. The query tier=frontend returns Pods A, C, and D.

Selectors

A selector is a question you ask about labels. Kubernetes supports two styles.

Equality-Based Selectors

These match exact values with =, ==, or !=.

kubectl get pods -l app=shop
kubectl get pods -l app=shop,env!=staging

A comma between conditions means AND. Every condition must hold for a pod to match.

Set-Based Selectors

These match against a group of values with in, notin, and exists.

kubectl get pods -l 'env in (production,staging)'
kubectl get pods -l 'tier notin (backend)'
kubectl get pods -l 'team'

The last command returns every pod that carries a team label, whatever its value.

How Other Objects Use Selectors

Services, ReplicaSets, and Deployments hold no list of pod names. Each one stores a selector and reads the live labels in the cluster.

 Service (selector: app=shop, tier=frontend)
        │
        ▼
 ┌─────────────────────────────────────┐
 │ Pods with matching labels           │
 │   Pod A  ✔  Pod C  ✔  Pod D  ✘     │
 └─────────────────────────────────────┘
        ▲
        │ owns and counts
 Deployment (selector: app=shop)

Pod D carries app=blog, so the service ignores it. Change a pod label and the service adds or drops that pod within seconds. Operators use this trick to pull a faulty pod out of traffic without deleting it: relabel the pod and it leaves the service but stays alive for debugging.

apiVersion: v1
kind: Service
metadata:
  name: shop-service
spec:
  selector:
    app: shop
    tier: frontend
  ports:
  - port: 80
    targetPort: 8080

Managing Labels with kubectl

# add a label
kubectl label pod cart-pod version=v2

# change an existing label
kubectl label pod cart-pod env=staging --overwrite

# remove a label (note the dash)
kubectl label pod cart-pod version-

# show labels as columns
kubectl get pods --show-labels

Annotations

Annotations store key and value pairs, but selectors cannot query them. They carry extra information for tools and humans: a build ID, a contact email, a link to documentation, or settings that an ingress controller reads.

FeatureLabelsAnnotations
PurposeIdentify and group objectsAttach descriptive data
Used by selectorsYesNo
Size limitSmall (63 characters per value)Large (up to 256 KB in total)
Typical contentapp, tier, envBuild number, owner, tool settings

Recommended Labels

Kubernetes publishes a shared set of label names so tools and teams speak the same language.

LabelMeaningExample
app.kubernetes.io/nameApplication nameshop
app.kubernetes.io/instanceUnique install nameshop-prod
app.kubernetes.io/versionCurrent version2.4.1
app.kubernetes.io/componentRole inside the appdatabase
app.kubernetes.io/part-ofLarger systemonline-store

Common Mistakes

  • A selector that matches too many pods sends traffic to the wrong application. Use at least two labels in selectors for shared namespaces.
  • A typo in a label value leaves a service with zero endpoints. Run kubectl get endpoints to confirm that pods attached.
  • Deployment selectors cannot change after creation. Plan the label scheme before the first deploy.
  • Annotations hold data, not identity. Pick labels whenever a selector needs to read the value.

Key Points

  • Labels are key and value pairs that identify objects.
  • Selectors query labels with equality or set-based rules.
  • Services, ReplicaSets, and Deployments find their pods through selectors.
  • Annotations store extra data that selectors never read.