07 - Labels and Selectors¶
What this session is¶
About 30 minutes. Labels are how Kubernetes finds things. Almost everything in K8s uses them - Services find pods by label, Deployments manage their pods by label, monitoring scrapes pods by label.
Labels¶
Labels are key=value pairs on resources, set in metadata:
Add or change labels on a running resource:
Selectors¶
Selectors query by label. Two forms:
Equality:
Set-based:
kubectl get pods -l 'app in (nginx,redis)'
kubectl get pods -l 'env notin (prod)'
kubectl get pods -l 'tier' # has the label, any value
kubectl get pods -l '!debug' # doesn't have the label
Use whichever fits. Equality is shorter; set-based is more flexible.
How K8s components use labels¶
Most controllers use selectors:
Service finds pods to route to:
Deployment manages pods matching its template:
kind: Deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx # MUST match the selector
NetworkPolicy allows/denies traffic to pods matching:
HorizontalPodAutoscaler finds pods to scale.
PodDisruptionBudget protects pods from voluntary disruption.
It's the universal "how do I find these things" mechanism. Master it.
Common label conventions¶
These conventions are widely followed. Use them in your own YAML:
| Label | Meaning |
|---|---|
app.kubernetes.io/name |
The application's name (e.g. nginx, redis). |
app.kubernetes.io/instance |
A specific install (e.g. nginx-prod). |
app.kubernetes.io/version |
App version. |
app.kubernetes.io/component |
Role (e.g. database, frontend). |
app.kubernetes.io/part-of |
Higher-level app (e.g. wordpress). |
app.kubernetes.io/managed-by |
Tool managing this (e.g. helm). |
A pod from a typical Helm chart will have all of these - useful for filtering ("show me all pods that are part of the wordpress app").
Inside a Deployment template, app: <name> (short form) is widely used and that's also fine for most cases.
Annotations vs labels¶
Labels are for selection. Short, indexed, queryable, limited in size.
Annotations are arbitrary metadata. Free-form, not queryable. Used for: build info, prometheus configs, ingress rules ("rewrite this path"), etc.
metadata:
labels:
app: nginx # for selection
annotations:
description: "the main web frontend"
deployed-by: "ci-build-#1234"
nginx.ingress.kubernetes.io/rewrite-target: "/"
You set annotations the same way (kubectl annotate ...). They don't drive controller behavior the way labels do.
Real-world: filter by labels¶
Find everything tagged with app=nginx:
Across all namespaces:
Show with the labels column visible:
Show specific label as a column:
These are daily-use commands. The --show-labels flag in particular is useful when debugging "why isn't my Service routing to my pod?" - answer is almost always "the labels don't match."
A common debugging pattern¶
"My Service has no endpoints." Almost always: the Service's selector doesn't match any pods.
kubectl describe service nginx
# Endpoints: <none> ← the smoking gun
kubectl get pods --show-labels
# you see pods with app=nginx-app, not app=nginx
Fix one or the other. Pods or the Service selector - make them match.
Exercise¶
-
Apply the nginx Deployment + Service from page 04. Confirm endpoints exist:
-
Filter by label:
-
Break selection on purpose:
Fix: -
Add an annotation:
What you might wonder¶
"What characters can be in label keys/values?"
Limited: alphanumeric, -, _, .. Length: ≤63 chars for value, key has a similar limit. If you need to store arbitrary text, use annotations instead.
"Why both labels and tags? (in some clouds)" Different worlds. Cloud tags (AWS, GCP) are on cloud resources. K8s labels are on K8s resources. Some tools sync between them; don't confuse the two.
"What's a 'selector' in a NetworkPolicy?" Same idea - pick pods by labels. NetworkPolicies allow/deny traffic between pods matching the selector. Beyond beginner; you'll meet them eventually.
Done¶
- Add labels to resources.
- Query with selectors (equality and set-based).
- Recognize the
app.kubernetes.io/*convention. - Distinguish labels (selectable) from annotations (free-form metadata).
- Debug "no endpoints" issues by checking labels.