diagram.mmd — flowchart
Kubernetes Service Routing flowchart diagram

A Kubernetes Service is a stable virtual IP and DNS name that provides a consistent endpoint for a set of pods, abstracting away the ephemeral nature of pod IP addresses and enabling both internal cluster communication and external traffic ingress.

Pods are mortal — they are created and destroyed as deployments scale or roll out updates, and each new pod receives a new IP address. A Service solves this by maintaining a stable ClusterIP and updating the Endpoints object whenever pods matching its label selector change. kube-proxy on each node programs iptables or ipvs rules to forward traffic destined for the ClusterIP to one of the ready pod IPs.

Kubernetes offers four Service types:

ClusterIP (default): Accessible only within the cluster. Other pods resolve the service via its DNS name (my-service.my-namespace.svc.cluster.local). Traffic is load-balanced round-robin across matching pods.

NodePort: Exposes the service on a static port (30000–32767) on every node's external IP. Useful for development or when no cloud load balancer is available.

LoadBalancer: Provisions a cloud provider load balancer (AWS ELB, GCP CLB, Azure LB) that forwards external traffic to the NodePort and then to pods. This is the standard production exposure mechanism for non-HTTP services.

ExternalName: Maps the service to a CNAME (e.g., an RDS hostname), allowing in-cluster pods to reference external services by Kubernetes DNS names.

Traffic routing to pods is gated by readiness probes — only pods reporting Ready receive traffic. See Kubernetes Ingress Routing for HTTP-level routing and Kubernetes Pod Lifecycle for pod state transitions.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

A Kubernetes Service is a stable virtual IP and DNS name that provides a consistent endpoint for a set of pods. It abstracts away the ephemeral nature of pod IP addresses by tracking ready pods via label selectors and updating iptables or ipvs rules on every node through kube-proxy whenever the set of matching pods changes.
ClusterIP exposes the service only within the cluster at a stable internal IP. NodePort additionally exposes the service on a static port on every node's external IP, useful for development. LoadBalancer provisions a cloud load balancer that forwards external traffic into the cluster, making it the standard production exposure mechanism for non-HTTP services.
kube-proxy runs on every node and programs iptables (or ipvs) rules that intercept traffic destined for a Service ClusterIP and DNAT it to one of the ready pod IPs. In iptables mode, rules are evaluated sequentially. In ipvs mode, a kernel-level virtual server is used for O(1) lookup and better performance at scale with thousands of services.
Forgetting to configure readiness probes means kube-proxy routes traffic to pods that are still initializing or experiencing errors. Using `NodePort` in production without a firewall exposes services on every node's IP. Setting `sessionAffinity: ClientIP` without understanding its caveats can create load imbalances. Missing `topologyAwareRouting` configuration in multi-zone clusters causes cross-zone traffic costs.
mermaid
flowchart LR ExtClient([External Client]) --> LB[Cloud Load Balancer\ntype: LoadBalancer] InternalPod([Internal Pod]) --> DNS[CoreDNS\nmy-svc.ns.svc.cluster.local] DNS --> ClusterIP[Service ClusterIP\nvirtual IP] LB --> NodePort[NodePort\n30080 on each Node] NodePort --> ClusterIP ClusterIP --> KubeProxy[kube-proxy\niptables / ipvs rules] KubeProxy --> Endpoints[Endpoints Object\nlive pod IPs] Endpoints --> PodA[Pod A\n10.0.1.5:8080] Endpoints --> PodB[Pod B\n10.0.1.6:8080] Endpoints --> PodC[Pod C\n10.0.1.7:8080] PodA --> ReadyA{Readiness\nProbe Ready?} PodB --> ReadyB{Readiness\nProbe Ready?} ReadyA -->|Yes| ServeA([Serving traffic]) ReadyB -->|No| SkipB([Excluded from endpoints])
Copied to clipboard