Skip to main content
This lesson explains how Kubernetes implements service networking: how Pods get IPs, how Services provide stable network endpoints, and how traffic to Service IPs/ports is forwarded to backing Pods across nodes. At the Pod level, each node typically creates a bridge or uses a CNI plugin to attach Pods into a virtual network. Each Pod receives its own network namespace, veth pair, and an IP from the node’s pod-subnet. Routing or overlay mechanisms (VXLAN, IP-in-IP, etc.) allow Pods on different nodes to communicate so the cluster forms a single routable pod network.
A network topology diagram showing three nodes with bridge v-net-0 subnets (10.244.1.0/24, 10.244.2.0/24, 10.244.3.0/24) and their gateway IPs on the 192.168.1.0 LAN. Each node displays container IPs and CNI/bridge details.
Instead of calling Pods by IP, you normally expose an application using a Kubernetes Service. A Service gives a stable virtual IP and a DNS name that other Pods (or external clients, depending on type) can use to reach the application. Quick example: to let the orange pod serve the blue pod, you create an orange Service. The Service is cluster-scoped (not tied to one node) and provides a stable ClusterIP and DNS name. Any Pod in the cluster can reach the orange application using that IP/name (unless network policies block access).

Common Service types

The simplest and most common type is ClusterIP. It exposes the Service only inside the cluster — a good fit for internal databases or microservices.
A diagram titled "ClusterIP" showing three Kubernetes node boxes with colored pod icons and their pod IPs. A dotted line links the pods to a cluster IP (10.99.13.178) and node IPs (192.168.1.11, .12, .13) are shown at the bottom.
If you must expose an application outside the cluster without a cloud load balancer, NodePort extends ClusterIP by opening a port on every node. External clients can connect to any node IP and the allocated NodePort to reach the Service.
A stylized "NodePort" diagram of a Kubernetes cluster with three nodes (Node 1–3) each exposing port 30080. It shows node IPs (192.168.1.x), pod IPs (10.244.x.x) and cluster-service IPs (10.99.13.x) with arrows indicating traffic flow.

How Services get IPs and forward traffic

Services are logical, cluster-scoped objects stored in the API server. There is no real process listening on the Service IP — the address is virtual. When you create a Service, the API server assigns an IP from the configured service CIDR (controlled by the API server option --service-cluster-ip-range). Each node runs two components relevant to Service networking:
  • kubelet — manages Pods on the node and interacts with the CNI to configure Pod networking.
  • kube-proxy — watches the API server for Services and Endpoints and programs forwarding rules on the node to map a Service IP:port to one of the backend Pod IP:ports.
A Kubernetes cluster diagram showing the kube-apiserver connected to three nodes. Each node displays kubelet and kube-proxy components and illustrates service IP:port forwarding to pod IPs.
kube-proxy implements this mapping using different proxy modes:
  • userspace (legacy)
  • iptables (widely used default)
  • IPVS (high-performance alternative)
The proxy mode is configured when kube-proxy starts. If not set explicitly, many distros use the iptables proxier.
A dark-themed diagram titled "Kube-proxy" with the "iptables" mode highlighted and a small table showing IP:Port 10.99.13.178:80 being forwarded to 10.244.1.2.
When a Service is added:
  1. The API server assigns a ClusterIP from the Service CIDR.
  2. kube-proxy on every node sees the new Service and programs kernel-level rules (iptables or IPVS) so traffic to that virtual IP:port is NATed to one of the endpoint Pod IPs:ports.
Example scenario
  • Pod db runs on node-1 with IP 10.244.1.2.
  • You create a ClusterIP Service named db-service; the API assigns 10.103.132.104 and the Service exposes port 3306.
  • kube-proxy on each node programs rules to DNAT traffic destined for 10.103.132.104:3306 to the backend pod 10.244.1.2:3306.
Commands and sample output:
Always allocate separate, non-overlapping CIDR ranges for Pod networks and Service networks (for example, Pod network 10.244.0.0/16 and Service CIDR 10.96.0.0/12). Overlapping CIDRs break routing and NAT, causing traffic to be misrouted.

Inspecting kube-proxy / iptables behavior

In iptables mode, kube-proxy inserts rules in the nat table so packets destined for the ClusterIP are DNATed to backend Pods. On a node you can list these rules:
How to read this:
  • The KUBE-SVC chain matches traffic to the Service IP 10.103.132.104 on port 3306.
  • A DNAT rule rewrites the destination to a selected backend pod IP 10.244.1.2:3306.
  • kube-proxy creates and manages these chains, adding comments with the Service name for identification.
If you do not see expected rules:
  • Confirm kube-proxy is running and connected to the API server.
  • Verify kube-proxy’s log output and configured proxy mode.
  • Check that Services and Endpoints exist (kubectl get svc, kubectl get endpoints).

kube-proxy logs

kube-proxy logs which proxier it uses and when it adds/removes Services or Endpoints. Example:
Notes:
  • kube-proxy log location depends on the distribution and deployment method (systemd, static Pod manifest, or DaemonSet). Adjust the path as needed.
  • Increase kube-proxy verbosity for troubleshooting (via --v flag) if necessary.

Summary

  • Services are virtual, cluster-scoped objects that receive an IP from the Service CIDR.
  • kube-proxy on each node programs kernel-level forwarding (iptables or IPVS) so traffic to a Service IP:port is DNATed to a backend Pod IP:port.
  • NodePort extends ClusterIP to make a Service reachable via any node IP and a fixed node port.
  • Ensure Pod and Service CIDRs do not overlap to avoid routing/NAT issues.
That’s it for service networking.

Watch Video

Practice Lab