Labels, Services, and discovery
Services find pods by label selectors. One mismatched label leaves healthy pods with no traffic.
Labels are the glue
Kubernetes objects find each other through labels and selectors, not by name. A Deployment's selector says which pods its ReplicaSets own. A Service's selector says which pods receive its traffic. A NetworkPolicy's selector says which pods a rule applies to. Kubernetes: Up & Running stresses how much flexibility this gives, because any object can be grouped any way. It also makes a single label mismatch silent. Nothing errors. The Service simply selects zero pods.
kubectl get svc waybill -o jsonpath='{.spec.selector}'; echo
kubectl get pods -n waybill --show-labels
kubectl get pods -n waybill -l app=waybill # does the Service's selector match anything?
kubectl get endpointslices -n waybill -l kubernetes.io/service-name=waybill
If the selector query returns nothing, so does the Service, however green the pods look.
From Service to pods
A Service gives a set of pods a stable virtual IP (the ClusterIP) and DNS name. The control plane continuously maintains EndpointSlices listing the addresses of pods that match the selector, marked by readiness. On each node, kube-proxy (or an eBPF data plane) programs the rules that send ClusterIP traffic to ready endpoints.
Two conditions must hold for a pod to receive traffic: it matches the selector and it is ready. "No endpoints" means the first condition failed. Endpoints that are all marked not ready point at the second, which is the “Pods, probes, and configuration” notes’ readiness probes.
DNS names
Cluster DNS gives every Service a name, <service>.<namespace>.svc.<cluster-domain>, usually with cluster.local as the domain. Pods get search domains for their own namespace, so waybill works from inside the namespace and waybill.waybill from elsewhere. The Networking for Operators track's ndots discussion explains the extra queries you see in DNS logs. Test from inside the cluster, not from your laptop:
kubectl run -it --rm dnsprobe --image=busybox:1.36 --restart=Never -- nslookup waybill.waybill
Migrating labels safely
Label migrations, such as adopting the recommended app.kubernetes.io/* labels, are a common source of empty Services. The safe sequence is expand and contract once more:
- Add the new labels to pod templates alongside the old ones, and roll out.
- Switch selectors (Services, NetworkPolicies, monitors) to the new labels.
- Remove the old labels in a later change.
Deployment selectors are immutable in apps/v1, so changing one means creating a new Deployment, a larger operation to plan separately.
Getting traffic in
- ClusterIP (default): reachable only inside the cluster.
- NodePort: also exposed on a port on every node.
- LoadBalancer: also asks the cloud provider for an external load balancer.
- Ingress / Gateway API: HTTP routing by host and path to Services, implemented by a controller (often a proxy such as those in the Networking for Operators track).
Whatever the entry point, the last hop is a Service and its endpoints, so the selector check above belongs in every "the app is unreachable" investigation.
Node labels and placement
Pods are matched to nodes the same way. A nodeSelector or a required node affinity in the pod template lists node labels that must be present, and the scheduler only considers nodes that have them. If no node matches, the pod stays Pending, and kubectl describe pod ends with an event such as "0/3 nodes are available: 3 node(s) didn't match Pod's node affinity/selector". Nothing else warns you. Renaming node labels, during a migration or a new node pool, strands every workload that still asks for the old name. Fix the workload's selector in its manifest rather than putting the old label back on nodes, which quietly undoes the rename for everyone who already moved.
Key terms
- Label
- A key/value pair on an object, such as
app.kubernetes.io/name=waybill, used for selection. - Selector
- A query over labels. A Service's selector decides which pods receive its traffic.
- EndpointSlice
- The objects listing the ready pod addresses currently behind a Service.
- ClusterIP
- A stable virtual IP for a Service inside the cluster, with a matching DNS name.
Read further
- Kubernetes Up & Running, 3rd edition, Ch. 6, "Labels and Annotations" (Purchase)
Label syntax, selector operators, and how labels connect objects. Note the difference between labels, which are for selection, and annotations, which hold arbitrary metadata. - Kubernetes Up & Running, 3rd edition, Ch. 7, "Service Discovery" (Purchase)
Service objects, cluster IPs, DNS names, readiness checks and endpoints, and the section on looking beyond the cluster. - Kubernetes Documentation, Concepts, Concepts → Services, Load Balancing, and Networking → "Service" and "DNS for Services and Pods" (Free online (CC BY 4.0))
Selectors and EndpointSlices, Service types, and the DNS naming scheme (<service>.<namespace>.svc.<cluster-domain>).