Services (ClusterIP, NodePort, LoadBalancer)
A Service is a stable virtual IP that load-balances to a changing set of Pod IPs. Three flavors differ only in where they expose that VIP.
Pods are ephemeral and their IPs change. A Service gives you a stable name and VIP that routes to whichever Pods currently match a label selector.
How it actually works
You create a Service with a selector. The endpoints controller watches Pods matching that selector and writes their IPs into an EndpointSlice. kube-proxy on every node watches EndpointSlices and programs iptables (or IPVS) rules: "traffic to ClusterIP X gets DNAT-ed to one of these Pod IPs."
When you curl my-service.my-ns, CoreDNS resolves it to the ClusterIP, your packet hits the kernel, iptables rewrites the destination to a real Pod IP. No proxy process in the path - it is all kernel netfilter.
The three types
- ClusterIP (default): a virtual IP reachable only inside the cluster. East-west traffic. This is what 90% of your services should be.
- NodePort: ClusterIP plus a port (30000-32767) opened on every node. Hit
nodeIP:nodePortfrom outside, kube-proxy forwards to a Pod. Good for development and bare metal, not for cloud. - LoadBalancer: NodePort plus the cloud provider provisions an actual load balancer (ELB, NLB, ALB on AWS) pointed at the node ports. This is how external traffic enters in cloud.
- ExternalName: just a CNAME. No proxy, no endpoints. Used to alias external services.
externalTrafficPolicy
Set this to Local on LoadBalancer Services to preserve the client IP and skip the extra hop. The downside: nodes without a Pod for that Service drop traffic, so your LB health checks must understand this. With Cluster (the default) you get one extra SNAT but every node can serve.
Headless Services
Set clusterIP: None and you get no VIP. DNS resolution returns all Pod IPs directly. This is what StatefulSets use so pods can address peers by hostname (web-0.my-headless-svc.ns.svc.cluster.local).
The interview answer
A Service is a stable VIP plus an EndpointSlice plus iptables rules programmed by kube-proxy. ClusterIP for internal, LoadBalancer for cloud-fronted public traffic, NodePort if you need a fixed port on bare metal. Headless when you want raw Pod IPs via DNS.
Learn more
- DocsServicekubernetes.io
- DocsEndpointSliceskubernetes.io