Skip to content

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.

metadata:
  labels:
    app: web
    environment: production
    version: "1.5"
    tier: frontend

Any resource can have any label. The only constraint: keys must be unique within a resource, and values must be strings.


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

selector:
  matchLabels:
    app: web
    environment: production

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:

spec:
  selector:
    app: web    # routes to any pod with app=web

Deployments manage Pods with matching labels:

spec:
  selector:
    matchLabels:
      app: web    # this deployment "owns" pods with app=web

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.