Labels, selectors and annotations
Labels, selectors and annotations
Both are key/value pairs in metadata. The difference is who reads them.
| Labels | Annotations | |
|---|---|---|
| Purpose | identify and select objects | attach non-identifying info |
| Used by | Services, ReplicaSets, scheduler, kubectl -l | tools, humans, controllers |
| Size | short (63 chars value) | up to 256 KB total |
| Example | app=web, env=prod, tier=frontend | description, build commit, Ingress settings |
metadata:
name: web-7d9f
labels:
app.kubernetes.io/name: web
app.kubernetes.io/part-of: shop
env: prod
annotations:
team.example.com/owner: "platform"
kubernetes.io/change-cause: "image 1.28"
Selectors
kubectl get pods -l env=prod # equality
kubectl get pods -l 'env!=prod'
kubectl get pods -l 'env in (dev,test),tier' # set-based; 'tier' = key exists
kubectl get pods -l '!tier' # key does not exist
kubectl get pods -L env,tier # labels as columns
kubectl get pods --field-selector status.phase=Running # fields, not labels
graph LR
S["Service<br/>selector: app=web"] --> P1["Pod app=web"]
S --> P2["Pod app=web"]
RS["ReplicaSet<br/>selector: app=web"] --> P1
RS --> P2
X["Pod app=db"]
Controllers find their Pods only through label selectors. Change a Pod’s label and it leaves the ReplicaSet and the Service - a common debugging trick.
Managing them
kubectl label pod web env=prod
kubectl label pod web env=dev --overwrite
kubectl label pod web env- # remove
kubectl annotate deploy web team.example.com/owner=platform
Use the recommended labels
app.kubernetes.io/* - Helm charts and dashboards expect them.