Kubernetes manages hundreds of Pods, Services, Deployments and other resources all at once. It needs a way to know which resources belong together, which Pods a Service should route to, which Pods a Deployment is managing. Labels are how all of this wiring works.
A label is a key-value pair you attach to any Kubernetes resource. They are simple strings — but they are the glue that connects everything in the cluster.
metadata:
labels:
app: my-app # what application this belongs to
env: production # which environment
version: v2 # which version
tier: frontend # which layer of the stack
You can put any labels you want. Kubernetes does not care about the names — you define what makes sense for your setup. But the labels you put on Pods must match what your Services and Deployments look for, otherwise nothing connects.
Without labels, a Service has no idea which Pods to send traffic to. A Deployment has no idea which Pods it created and is responsible for. Everything would be disconnected.
Service with selector "app: backend":
Scans all Pods in the cluster
Finds every Pod with the label app: backend
Routes traffic to those Pods — and only those Pods
Deployment with matchLabels "app: backend":
Tracks every Pod with the label app: backend
If one crashes, it creates a new one with that same label
The replacement is automatically picked up by the Service too
This is also why you must be careful with labels. If two different apps accidentally use the same label, a Service meant for one will start routing to the other.
# Deployment creates Pods with this label
spec:
selector:
matchLabels:
app: backend # Deployment manages Pods with this label
template:
metadata:
labels:
app: backend # every Pod gets this label
# Service routes to Pods with this label
spec:
selector:
app: backend # matches the label on the Pods above
The Deployment and the Service never reference each other directly. They both just look for Pods with app: backend. The label is the shared contract between them.
A selector is how you query resources by their labels — either from kubectl on the command line, or from inside a resource definition like a Service or Deployment.
# Service selector — routes to Pods matching ALL of these labels
spec:
selector:
app: backend
env: production # Pod must have BOTH labels to be selected
Multiple labels in a selector work as AND — the Pod must have every label listed to match. A Pod with app: backend but env: staging would NOT be selected here.
kubectl get pods -l app=my-app # Pods with this label
kubectl get pods -l env=production,app=backend # Pods with BOTH labels (AND)
kubectl get pods -l env!=staging # Pods where env is NOT staging
kubectl get pods -l 'env in (production,staging)' # Pods where env is either value
kubectl get all -l app=my-app # all resource types with this label