A Service is a stable front. Behind it is a list that changes all the time.
The list
For every Service with a selector, the cluster keeps an Endpoints object with the same name: the IPs and ports of every Ready Pod the selector matches.
learner@shallows:~$ kubectl get endpoints market-web
NAME ENDPOINTS AGE
market-web 10.42.0.8:80,10.42.0.9:80,10.42.0.10:80 5sDelete a Pod and its address leaves the list. The Deployment makes a new Pod and its address joins. Scale to five and two more appear.
Newer clusters also keep EndpointSlices, the same information cut into chunks for very large Services. kubectl get endpointslices shows them. For reading, the Endpoints object is enough.
The first thing to check
describe shows the list on one line:
learner@shallows:~$ kubectl describe svc market-web
Selector: app=market-web
IP: 10.96.248.109
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.42.0.8:80,10.42.0.9:80,10.42.0.10:80When a Service "does not work", read Endpoints: first:
| Endpoints | Meaning |
|---|---|
<none> | The selector matches no Ready Pod: a label typo, or the Pods are not Ready |
| A list, but connections are refused | The port on the Pod is wrong (next lesson) |
| A list, and it works | The Service is fine; look at the client |
Compare the Selector: line with kubectl get pods --show-labels. One wrong letter in a label and the list is empty, and nothing warns you.