Labels & Selectors
Tag resources with key-value metadata and use selectors to wire Services, Deployments, and queries together.
What Are Labels?
Labels are key-value pairs attached to metadata fields in Kubernetes API objects. They are key to the design of Kubernetes, enabling loose coupling between resources. Instead of hardcoding relationships (e.g., pointing a Service to a specific Pod name), objects query other objects dynamically using labels.
metadata:
labels:
app: web
tier: frontend
env: production
version: v2Label keys have two optional parts: a prefix (up to 253 characters, domain-style) and a name (up to 63 characters). The Kubernetes community uses recommended keys prefixed with app.kubernetes.io/ (e.g., app.kubernetes.io/name, app.kubernetes.io/part-of).
Visualizing Service Selectors
+---------------------+
| Service Object |
| selector: app=web |
+---------------------+
|
v (EndpointSlice Controller watches label changes via Informer)
+---------------------+
| EndpointSlice (EP) | <--- Contains IPs: [10.244.1.5, 10.244.2.12]
+---------------------+
|
+---------+---------+ (kube-proxy syncs to nodes)
| |
v v
+------------------+ +------------------+
| Node 1 | | Node 2 |
| iptables / IPVS | | iptables / IPVS |
| rules updated | | rules updated |
+------------------+ +------------------+
| (routes traffic) | (routes traffic)
v v
+------------------+ +------------------+
| Pod: app=web | | Pod: app=web |
| IP: 10.244.1.5 | | IP: 10.244.2.12 |
+------------------+ +------------------+The Reconcile Loop & Selectors
Under the hood, labels and selectors power the Reconcile Loop β the core control mechanism of Kubernetes.
- Informer Caches: Controllers (like the ReplicaSet controller or the EndpointSlice controller) run in the
kube-controller-manager. They register a Watch on the kube-apiserver for specific resource types. - Label Matching: When a new Pod is created or labeled, the EndpointSlice controller filters Pods using the label selector defined in a Service.
- Endpoint Propagation: The controller generates or updates an
EndpointSliceobject listing the IPs of all matching Pods. - Data Plane Updates:
kube-proxyrunning on every node watches the API server for changes to Services and EndpointSlices. Upon notification, it updates the node's packet-routing configuration:
- iptables mode: Updates chaining rules to randomly distribute connections across target Pod IPs using the statistic module.
- IPVS mode: Inserts entries into an in-kernel IPVS hash table, supporting faster routing and advanced load-balancing algorithms (e.g., least connections).
Labels vs Annotations
While both store key-value metadata, they have distinct roles:
| Feature | Labels | Annotations |
|---|---|---|
| Queryable/Selector-friendly | Yes (via label selectors in API queries and manifests) | No (cannot be used to filter resources in API requests) |
| Character Limits | Max 63 characters for keys/values, strict alphanumeric format | No strict length limits (can store large strings like JSON) |
| Primary Use Cases | Dynamic grouping, Service targeting, scheduling constraints (NodeSelector) | CI/CD metadata (git hash, build ID), tool config (Ingress controllers, annotations for cert-manager) |
Orphaned Pods
If you modify a Pod's labels such that they no longer match a Deployment's replica selector, the Deployment's controller immediately detects that the actual state (N - 1 matching pods) does not match the desired state (N). It spins up a new Pod to restore the replica count. The original Pod remains running as an orphan, disconnected from both the Deployment's control loop and the Service's traffic routing.
Querying With kubectl
# Equality-based kubectl get pods -l app=web kubectl get pods -l app=web,tier=frontend # Set-based (comma = AND) kubectl get pods -l 'tier in (frontend,backend)' kubectl get pods -l 'env notin (staging)'