Service and EndpointSlice
A Service is a stable name for a moving set of Pods, so which of them take traffic now? The EndpointSlice controller records the IP of each Pod matching the selector as one endpoint with its conditions, up to 100 per slice by default. When a failing readiness probe turns a Pod Ready=False, the container keeps running and its endpoint turns ready=false unless the Service sets publishNotReadyAddresses, and kube-proxy writes rules for the ready endpoints.
Play the animation 4 steps, animated, best on a wide screen
Service and EndpointSlice, step by step
-
The Service web holds a selector, app=web, and no list of backends. All three Pods carry that label, so all three match. Matching is not serving: 10.244.3.9 is failing its readiness probe, so its Ready condition is False.
Play from step 1 -
The EndpointSlice controller watches every matching Pod and writes one endpoint per Pod with an IP: its address and conditions, with the port stated once for the slice. 10.244.3.9 is listed with ready=false, so it stays out of the serving set. By default a slice holds up to 100 endpoints, and a bigger Service gets more slices.
Play from step 2 -
Readiness, not liveness, decides who serves. After 3 failed readiness probes in a row, the failureThreshold default, the Kubelet sets the Ready condition of 10.244.2.7 to False, and the controller sees that through its watch. It rewrites the endpoint to ready=false. The container is not restarted, and one passing probe by default turns the Pod and its endpoint ready again.
Play from step 3 -
The kube-proxy on every Node watches EndpointSlices, never the Pods. It writes Service rules for the ready endpoints, so traffic to web now reaches 10.244.1.5 alone. The slice is the contract between what is ready and where packets go.
Play from step 4