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.
| Feature | Labels | Annotations |
|---|---|---|
| Purpose | Identify and group objects | Attach descriptive data |
| Used by selectors | Yes | No |
| Size limit | Small (63 characters per value) | Large (up to 256 KB in total) |
| Typical content | app, tier, env | Build number, owner, tool settings |
Recommended Labels
Kubernetes publishes a shared set of label names so tools and teams speak the same language.
| Label | Meaning | Example |
|---|---|---|
| app.kubernetes.io/name | Application name | shop |
| app.kubernetes.io/instance | Unique install name | shop-prod |
| app.kubernetes.io/version | Current version | 2.4.1 |
| app.kubernetes.io/component | Role inside the app | database |
| app.kubernetes.io/part-of | Larger system | online-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 endpointsto 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.
