Labels are the glue between objects
A label is a key and value attached to an object, such as app=checkout or tier=web. A selector is a query that picks every object whose labels match. Kubernetes uses this one mechanism almost everywhere: a Service chooses its backend Pods, a Deployment chooses which Pods it owns, a NetworkPolicy chooses which Pods it protects, and kubectl get pods -l app=checkout filters your view.
The key design point is loose coupling. A Service never lists Pod names. It stores a selector, and the endpoint controller continuously computes the matching ready Pods. When a Deployment replaces a Pod, the new Pod carries the same labels, so the Service picks it up within seconds without anyone editing anything.
Selectors come in two forms: equality (app=checkout) and set-based (tier in (web, api), or just the existence of a key). Annotations look similar but are not selectable; use them for data that tools read, like ingress controller settings.
Reveal the Service, the Pods, then the matching. Gotcha: a typo in a label silently selects nothing. A Service with no endpoints is the classic symptom, so check kubectl get endpointslices when traffic does not arrive.