The Kubernetes Service Is the Whole Reason Pods Can Be Cattle

April 14, 2026


In Kubernetes, clients do not talk to pods. They talk to a Service. That swap, from "the thing that runs my code" to "a stable name in front of it," is the single design decision that lets the rest of Kubernetes work. Take it away and nothing else holds.

Think about what pods actually do during a normal week. They start. They crash. They get OOM-killed. They get evicted off a draining node. They get rescheduled to a new node with a new pod IP. A rolling deploy tears down every pod for a service and stands up new ones, intentionally. Autoscaling adds and removes them in response to load. If a caller had to track pod IPs, every one of these events would break every caller. Every deploy would be an outage. Every node drain would page someone.

The Service is the abstraction that absorbs all of that. From the caller's side, the Service is one name, one virtual IP, one contract: "send traffic here, and you will reach a healthy instance of payments." From the cluster's side, the Service is bound to a label selector, and the control plane continuously reconciles a list of pods that match the selector. Pods come and go beneath the Service. The name does not change.

The piece of the design that makes this contract honest is the Endpoints object, and the readiness probe that feeds it. The Endpoints object is the live list of pod IPs the Service is allowed to route to. A pod is only in that list when its readiness probe is passing. A pod that just started, but has not finished loading its config or warming its in-memory cache, is in the cluster but not in Endpoints. Traffic does not reach it until the probe says yes. That gate is what makes pods feel disposable instead of dangerous.

The failure mode I have watched on real clusters is a Deployment shipped with no readiness probe, or one wired to /health when /health only checks that the process is alive. A rolling deploy starts. New pods are added to Endpoints the instant the container is running. The Service routes traffic to pods that are still parsing config, still establishing database pools, still JIT-warming. Every deploy produces a five to ten second burst of 5xxs while the cluster looks healthy on the dashboard. The Service abstraction is working exactly as designed. It is the readiness probe that is lying.

The fix is small: every Deployment must have a readiness probe that reflects actual readiness, not process liveness. Hit an endpoint that returns 200 only when the pod can serve real traffic. Once that is true, the Service becomes a real contract instead of a polite suggestion, and pods can finally be cattle.

Key takeaway

The Service is a stable contract for callers, and the Endpoints object plus the readiness probe are what make that contract honest. Skip the readiness probe and the abstraction silently routes traffic to half-warm pods on every deploy.

Originally posted on LinkedIn. View original.


All Rights Reserved.