Kubernetes·6 min read·

Services, Labels, and Selectors: How Traffic Reaches Your Pods

Understand labels and selectors so you can build Services that route traffic to exactly the right pods, and avoid common misrouting bugs.

NB

Netbay Cloud Team

Netbay Engineering

On this page

Services are the stable front door for ephemeral pods, but a Service is only as good as the label selector it uses. The selector is how Kubernetes decides which pods the Service forwards to. If labels and selectors do not match, you get a Service with no endpoints and a confusing outage. This post unpacks how labels and selectors work together and how to avoid the classic mismatch.

What labels are

Labels are arbitrary key/value pairs attached to objects, like app: web or env: prod. They are not unique — many objects can share the same label. They are purely organizational metadata used for grouping, filtering, and selection. You declare them in the pod template and can add or modify them at any time.

What selectors are

A selector is the query that picks objects by their labels. Services, Deployments, ReplicaSets, and NetworkPolicies all use selectors to decide what they manage or route to. Deployment selector.matchLabels must match the labels in the pod template, and a Service selector must match the labels its target pods carry.

yaml
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  selector:
    app: api
    tier: backend
  ports:
    - port: 80
      targetPort: 8080

This Service only routes to pods that carry both app: api and tier: backend.

The matching rules

Selectors are designed to be broad enough to match a set, but a single typo silently produces zero endpoints. These rules matter:

  1. A Service selector is an AND of all its label key/value pairs.
  2. Selector keys and values are case-sensitive.
  3. Selectors can also use expressions, like app in (api, worker), for more flexible matching.
  4. Every field you put in selector.matchLabels must be present in the pod's labels, or the Service finds nothing.
yaml
apiVersion: v1
kind: Service
metadata:
  name: api-broad
spec:
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 8080

Diagnosing a no-endpoints Service

When traffic stops, the first thing to check is whether the Service has endpoints at all. The debugging loop is short and specific.

bash
kubectl get svc api
kubectl get endpoints api
kubectl get pods --show-labels
kubectl describe svc api

Compare the selector shown in describe output with the actual pod labels. The mismatch is almost always a spelling difference or a missing label key.

How the routing pipeline fits together

Three candidate pods pod A app=api, tier=web pod B app=api, tier=backend pod C app=worker selector: app=api AND tier=backend endpoint added pod B only

Keep labels intentional

A small convention saves hours of debugging. Give every workload an app label and an env label, and make selectors reference those consistently. Treat labels as the contract between a Service and the pods it serves — change one side, and the other breaks silently.

Takeaway

Labels are metadata; selectors are the query. A Service routes to precisely the pods whose labels satisfy its selector, and any mismatch means zero endpoints. Debug with get svc, get endpoints, and get pods --show-labels. When you want to test this on a real cluster, launch a Netbay VPS, install k3s, and experiment with selectors until one deliberately misroutes — netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance