# Demonstration: A Service With Zero Endpoints This is one of the most common "it just doesn't work" incidents in real Kubernetes operation — and it produces no error message at all at the Service level. ## The setup A Service `api-svc` selects Pods labeled `app: api`. A Deployment was recently updated and its Pods now carry the label `app: api-v2` instead (a rename during a refactor, deliberately or accidentally). ## What you'd see from the client side ``` $ curl http://api-svc:8080/health curl: (7) Failed to connect to api-svc port 8080: Connection refused ``` Just a generic connection failure — nothing here says "your Service's selector doesn't match any Pods." ## What the Service object itself shows ``` $ kubectl get service api-svc NAME TYPE CLUSTER-IP PORT(S) AGE api-svc ClusterIP 10.96.34.201 8080/TCP 2h ``` Completely normal-looking. The Service exists, has a stable IP, is not in any kind of "error" state — because from the Service's own perspective, nothing is wrong. It's doing exactly what it's configured to do: route to whatever matches its selector, which currently happens to be nothing. ## Where the real evidence is: Endpoints ``` $ kubectl get endpoints api-svc NAME ENDPOINTS AGE api-svc 2h ``` This is the actual signal. `` means the Service's selector currently matches zero Pods — this is the single fastest check for "is this a Service-to-Pod mismatch" any time something reachable-in-principle looks like a connection failure. ## Confirming the mismatch ``` $ kubectl get pods --show-labels NAME READY STATUS LABELS api-abc123 1/1 Running app=api-v2 ``` The Pod is healthy and running — `app=api-v2`, not `app=api`. The Service's selector (`app: api`) matches nothing, and nothing about the Pod itself is broken. ## The general diagnostic shape `curl`/application-level connection failure tells you *that* something's wrong, but nothing about *where*. `kubectl get endpoints ` is the fastest way to distinguish "the Service has no matching Pods" from "the Pods exist and are ready but something else is wrong" — reach for it early whenever a Service-fronted connection fails for no obvious reason. ## Instructor Notes **Demo script:** Live-create this exact mismatch (a Service with one selector, a Deployment with a slightly different label) and walk through `kubectl get service` -> `kubectl get endpoints` -> `kubectl get pods --show-labels` in front of the class, narrating what each command is and isn't telling you. **Approximate timing:** 8-10 minutes live; 5-7 minutes self-paced. **Common misconception to preempt:** students often check the Service object first and, seeing nothing obviously wrong, assume the problem must be elsewhere entirely (DNS, firewall, the application itself) — reinforce that `kubectl get endpoints` is the specific, fast check for this exact failure mode, before reaching for anything more complex. **Optional extension:** ask what `kubectl describe service api-svc` would additionally show compared to `kubectl get service` (answer: the same selector the Service is using, which lets you directly compare it against `kubectl get pods --show-labels`'s actual Pod labels side by side, rather than inferring the mismatch).