15 · Labels & Selectors
Labels are key-value pairs attached to any Kubernetes resource. Selectors filter resources by labels. Together, they are the glue that connects Deployments to Pods, Services to Pods, NetworkPolicies to namespaces, and everything in between.
What Labels Are
A label is a key-value pair with no inherent meaning to Kubernetes — it only matters to the humans and controllers that interpret it.
Any resource can have any label. The only constraint: keys must be unique within a resource, and values must be strings.
Recommended Label Conventions
The Kubernetes project recommends a standard set of labels under the app.kubernetes.io/ prefix:
| Label | Example | Purpose |
|---|---|---|
app.kubernetes.io/name |
mysql |
Application name |
app.kubernetes.io/version |
8.0.36 |
Application version |
app.kubernetes.io/component |
database |
Component role |
app.kubernetes.io/part-of |
my-platform |
Parent application |
app.kubernetes.io/managed-by |
helm |
Tool that manages this resource |
app.kubernetes.io/instance |
mysql-prod |
Unique instance name |
Using these consistently makes it easy to query across a cluster and enables tooling (Helm, Argo CD, dashboards) to understand your workloads.
How Selectors Work
A selector is a filter expression that matches resources by their labels.
Equality-based
All conditions must match. This selects resources that have both app=web AND environment=production.
Set-based
selector:
matchExpressions:
- key: environment
operator: In
values: [production, staging]
- key: tier
operator: NotIn
values: [debug]
- key: release
operator: Exists
More expressive. Operators: In, NotIn, Exists, DoesNotExist.
Why Labels Are the Foundation
Labels drive every piece of Kubernetes orchestration:
Services route traffic to Pods with matching labels:
Deployments manage Pods with matching labels:
NetworkPolicies restrict traffic between namespaces and pods based on labels.
PodAffinity/Anti-affinity schedules Pods relative to other Pods by their labels.
kubectl filters by labels:
kubectl get pods -l app=web
kubectl get pods -l 'environment in (production,staging)'
kubectl get pods -l app=web,environment=production
Labels vs Annotations
They look similar but serve different purposes:
| Labels | Annotations | |
|---|---|---|
| Used for | Selection and filtering | Non-identifying metadata |
| Queried by | Kubernetes controllers, kubectl | Tools and humans |
| Examples | app, version, environment |
description, git-commit, contact-email |
| Size limit | Small (identifying) | Large (can be URLs, JSON, long strings) |
Annotations carry metadata that controllers and tooling read but don't use for selection. Examples: kubectl.kubernetes.io/last-applied-configuration, cert-manager annotations, Prometheus scrape annotations.
Common Patterns
Feature flags via labels: label a Deployment with traffic=enabled and write a Service selector that only targets labelled Pods. Removing the label removes the Pods from the Service endpoint — instant traffic cutoff without scaling down.
Multi-environment in one cluster: label resources with environment=dev and environment=staging. Use label selectors in monitoring, NetworkPolicy, and resource quotas to apply environment-specific rules.
Canary deployments: run two Deployments (version=stable, version=canary) with a shared app=web label. The Service routes to both. Control traffic split by adjusting replica counts.