The Kubernetes Network Model
Kubernetes networking looks like magic until you see the three distinct networks underneath it and the small set of rules every CNI must satisfy.
Summary
- Definition: The Kubernetes network model is a contract that requires a flat, NAT-free network across three address spaces: pod IPs, Service (cluster) IPs, and node IPs.
- Insight: Kubernetes specifies the contract but implements almost none of it; the CNI and kube-proxy (or a CNI replacement) do the work.
- Key Concepts: the flat-network assumption, pod CIDR, Service CIDR, node network, and kube-proxy.
- When to Use: internalize this before writing policy, debugging connectivity, or choosing a CNI.
- Limitations/Trade-offs: the model guarantees reachability, not security; isolation is bolted on with NetworkPolicy.
- Related Topics: why the network is open by default, CNI comparison, and DNS egress.
Foundations
The model rests on four requirements. Pods on any node reach pods on any node without NAT.
Nodes reach all pods, and pods reach all nodes, again without NAT. A pod's own view of its IP matches the IP others use to reach it.
That last point matters. Inside the container, ip addr shows the same address that a peer dials, so applications never need to know they are behind a translation layer.
This is intentionally simpler than the classic Docker single-host bridge model, where containers got a private subnet behind host NAT.
Kubernetes rejects that per-host NAT approach cluster-wide. The result feels like one big L3 network where every pod is a first-class routable host.
The trade is that the platform gives you reachability but no built-in segmentation. Security is a separate layer you add on purpose.
Mechanics & Interactions
There are three address ranges to keep straight. Confusing them is the root of most networking bugs.
The pod network (pod CIDR) is where pods live. Each pod gets a unique IP from this range, and these IPs are ephemeral - they change on reschedule.
The Service network (Service CIDR, set by --service-cluster-ip-range) holds ClusterIPs. These are virtual: no interface owns them, and they exist only as forwarding rules.
The node network is the real infrastructure network the nodes sit on, managed by your cloud or data center, not by Kubernetes.
The CNI owns the pod network. It allocates pod IPs and makes them routable, using an overlay like VXLAN or Geneve, or native routing via BGP or cloud route tables.
kube-proxy owns the Service network. It watches Services and Endpoints and programs the node's dataplane so ClusterIP traffic is DNAT'd to a healthy backend pod IP.
Modern kube-proxy uses nftables or IPVS; the older iptables mode still exists. Some CNIs, notably Cilium, can replace kube-proxy entirely with eBPF.
DNS ties it together. CoreDNS runs as pods, gets a stable ClusterIP, and resolves Service names like svc.namespace.svc.cluster.local to those ClusterIPs.
So a typical call is: app resolves the name via CoreDNS, gets a ClusterIP, kube-proxy DNATs to a pod IP, and the CNI routes the packet to the right node.
Advanced Considerations & Applications
The three-network split explains why NetworkPolicy operates on pod IPs and labels, not on Service names or ClusterIPs.
By the time a packet is evaluated at the destination, kube-proxy has already rewritten the ClusterIP to a pod IP. Policy sees pods, so you write policy against pod labels.
The AWS VPC CNI is a notable variation: it assigns real VPC IPs to pods from ENIs, so pod and node networks share the same address space with no overlay.
That gives native performance and VPC-native routing, but pod IP density is bounded by ENI and instance limits, which shapes how many pods a node can run.
Overlay CNIs decouple pod IPs from the underlying network, which is portable and dense but adds encapsulation overhead and can complicate packet capture.
Understanding whether your cluster overlays or routes natively determines how you debug MTU issues, trace packets, and reason about egress source IPs.
Common Misconceptions
"The Service IP is a real address on some pod." No. ClusterIPs are virtual forwarding constructs; no NIC holds them, and you cannot ping one meaningfully in all setups.
"kube-proxy load-balances at L7." It does L3/L4 DNAT with connection-level balancing. HTTP-aware routing needs an Ingress, Gateway, or service mesh.
"Pod IPs are stable." They are ephemeral. Rely on Services, DNS, or labels, never on a pinned pod IP.
"Every cluster uses an overlay." Native-routing CNIs (AWS VPC CNI, Calico in BGP mode) avoid overlays and put pods directly on the routed network.
"NetworkPolicy can target a Service." It targets pods by label and namespaces or CIDRs. Service abstractions are invisible to policy evaluation.
FAQs
What actually implements the flat network? The CNI plugin, invoked by the kubelet when each pod starts, plus the dataplane it programs.
Where do ClusterIPs come from? From the Service CIDR configured on the API server; kube-proxy or a CNI turns them into forwarding rules.
Why can I not ping a pod from my laptop? The pod CIDR is usually internal to the cluster and not routed to your workstation, especially with overlays.
Does the model require an overlay? No. It requires reachability without NAT; overlay and native routing are two valid ways to achieve it.
How does DNS fit the model? CoreDNS is just pods behind a ClusterIP, so name resolution follows the same Service and pod-network mechanics as any workload.
Where does NetworkPolicy sit? It constrains traffic on the pod network, evaluated by the CNI's policy engine after Service translation.
Related
- Why the Cluster Network Is Open by Default
- Network Policies Basics
- CNI Comparison
- DNS Egress Policies
- Network Policies Best Practices
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).