What is a Kubernetes Service and what problem does it solve?
Quick Answer
A Service provides a stable network endpoint (DNS name and virtual IP) that routes traffic to a set of Pods selected by labels. It solves the problem that Pods are ephemeral — they get new IP addresses every time they restart — so clients need a stable way to reach them.
Detailed Answer
Imagine you're calling a customer support line. You don't call a specific agent's personal phone number — you call the main support number, and the phone system routes you to whichever agent is available. If one agent goes on break, the system automatically sends your call to another. The main number never changes even though the agents behind it constantly rotate.
A Kubernetes Service works the same way. Pods come and go — they crash, get rescheduled, scale up and down — and each time they get a brand new IP address. If your frontend tried to connect directly to a backend Pod IP, it would break every time that Pod restarted. A Service gives you a stable virtual IP (called a ClusterIP) and a DNS name (like payments-api.production.svc.cluster.local) that never changes. Behind the scenes, the Service watches for Pods that match its label selector, and maintains a list of healthy Pod IPs called Endpoints.
When traffic hits the Service IP, kube-proxy on each node handles the routing. In the default iptables mode, kube-proxy writes iptables rules that randomly distribute connections across all healthy backend Pods. In IPVS mode (used at scale), it uses the Linux kernel's IPVS load balancer for better performance with thousands of backend Pods. The key insight is that the Service IP is virtual — no network interface actually has this IP. It only exists as iptables/IPVS rules that intercept packets and DNAT (destination NAT) them to a real Pod IP.
There are four Service types, each building on the previous: ClusterIP (default — only reachable inside the cluster), NodePort (exposes the Service on a static port on every node's IP), LoadBalancer (provisions a cloud load balancer that points to the NodePorts), and ExternalName (a CNAME alias to an external DNS name, no proxying). In production, most internal services use ClusterIP, while services that need external access use LoadBalancer or an Ingress controller.
A subtle but important gotcha: Services use label selectors to find Pods, and the Endpoints controller only includes Pods that are both Running AND pass their readiness probe. This means if your readiness probe is misconfigured — say it checks a dependency that's temporarily down — the Service will remove all your Pods from its Endpoints, causing a complete outage even though the Pods are actually running. Always make readiness probes check only whether your application can handle requests, not whether its dependencies are healthy.