Skip to main content
In this lesson we explain how Kubernetes implements pod networking, what it requires from a network solution, and how Container Network Interface (CNI) plugins automate the per-pod networking steps that an administrator would otherwise perform manually. So far we’ve assumed you have a multi-node Kubernetes cluster with the control plane and kubelets running and nodes able to reach one another over the underlying physical or cloud network (firewalls/security groups configured accordingly). Before deploying applications you must decide how pods are addressed and how they communicate across nodes—Kubernetes delegates that responsibility to a pluggable CNI networking solution.

Kubernetes pod networking model — requirements

Kubernetes defines a simple, powerful pod networking model. Any networking solution must satisfy these requirements:
  • Every pod gets a unique, routable IP address.
  • A pod can reach every pod on the same node using that IP.
  • A pod can reach every pod on other nodes using that IP.
  • Pod-to-pod communication must not require NAT.
Kubernetes does not mandate specific IP ranges. You can choose any private address space, but the CNI implementation must automatically assign IPs and configure connectivity across nodes so those IPs are routable cluster-wide. Understanding how a CNI plugin satisfies these requirements requires basic knowledge of Linux networking primitives: network namespaces, veth pairs, bridges, and routing.

Building block: network namespaces, veth pairs and bridges

On Linux, you can implement pod networking with network namespaces and veth pairs. At a high level, each node performs:
  1. Create a node-level L2 device (a bridge, VXLAN device, or other datapath) and give it an IP/gateway for that node’s pod-subnet.
  2. For each pod, create a veth pair. Place one end in the pod’s network namespace and attach the other end to the node datapath.
  3. Assign the pod IP in the pod-subnet and set a default route via the node datapath IP.
  4. Ensure routing between pod-subnets across nodes.
The commands below illustrate these steps on a single node (run as root). They show the simplest bridge-based datapath for a node that uses 10.244.1.0/24 as its pod subnet.
If each node uses a distinct per-host subnet (for example 10.244.1.0/24 on node1, 10.244.2.0/24 on node2), pods on the same node can now reach each other. The next step is to enable cross-node routing so pod IPs on different nodes can reach one another.

Inter-node routing: simple static approach

To reach a pod on another node, each host must know how to route to that node’s pod subnet. If pod 10.244.1.2 on node1 wants to reach pod 10.244.2.2 on node2, node1 needs a route for 10.244.2.0/24 via node2’s host IP (for example 192.168.1.12):
Without the route, a pod ping fails:
After programming the host routes, inter-node pod-to-pod connectivity works:
Maintaining static host routes for many nodes is error-prone. Alternatives:
  • Program routes centrally on the cluster router (aggregate per-node subnets into a single route such as 10.244.0.0/16).
  • Use an overlay (VXLAN, GRE) to encapsulate pod traffic between hosts.
  • Use a routing-based datapath (BGP/MPLS) where nodes advertise pod subnets automatically.
Many CNI plugins automate route distribution or encapsulate traffic so you don’t have to manage per-host routes manually.

Automating the per-pod steps: where CNI fits in

The manual sequence we ran for each pod (create veth, move into namespace, attach to bridge, assign IP, configure route) must be performed automatically and coordinated with the container runtime. Thousands of pods can be created or destroyed per minute, so this process must be programmatic and reliable. The Container Network Interface (CNI) is the integration layer between Kubernetes (the kubelet and container runtime) and the network implementation. The runtime invokes a CNI plugin binary for pod lifecycle events and provides JSON configuration on stdin describing the pod, namespace, and desired network. The plugin performs the networking work and returns the result (including the allocated IP) to the runtime. A minimal set of actions a CNI plugin typically performs on ADD (attach a pod to the network):
  • Create a veth pair.
  • Move one end into the pod’s network namespace.
  • Attach the host end to the node datapath (bridge, VXLAN device, or kernel datapath).
  • Allocate and assign a pod IP from IPAM.
  • Set up the pod’s default route and any necessary iptables rules.
On DEL, the plugin must remove the network interface(s) and free the IP via its IPAM component. Template of the sequence performed by a CNI plugin (pseudocode):
Note: Always use ip -n <namespace> ... or ip netns exec <namespace> ... when operating inside a network namespace.
CNI plugins commonly include an IPAM (IP address management) component and implement different datapaths — Linux bridge, VXLAN overlay, host-gw with routing, BGP-based routing, or eBPF datapaths. Choose a CNI that matches your cluster scale, performance, and operational model.

How the container runtime invokes CNI

Kubelet (or the container runtime) is configured with a CNI configuration file and a filesystem path to the CNI plugin binaries. For a pod lifecycle event:
  1. Kubelet prepares the JSON configuration describing the pod: pod name, namespace, container ID, and network configuration.
  2. Kubelet executes the CNI binary with the ADD command and passes the JSON on stdin.
  3. The CNI plugin allocates/configures the network interface(s), programs routes and firewall rules as needed, and returns a JSON result with the assigned IP.
  4. On pod deletion, kubelet calls the CNI binary with DEL so the plugin can tear down the interface and release the IP.
This handshake is standardized by the CNI specification, which is why Kubernetes can support many different networking implementations by simply dropping the plugin binaries and configuration into the proper directories.

Summary

  • Kubernetes requires each pod to have a routable IP and peer-to-peer connectivity across nodes without NAT.
  • Pod networking in Linux is built from primitives: network namespaces, veth pairs, bridges or other datapaths, and routes.
  • Inter-node routing can be handled with static host routes, a centralized router, overlays (VXLAN), or dynamic routing (BGP). CNIs automate these choices for you.
  • The CNI specification standardizes how kubelet and the container runtime call network plugins to attach/detach pod interfaces and manage IP addresses.

Watch Video