Stage 3 · Build
Networking Stack Deep Dive
Network Namespaces & CNI
Container networking, veth pairs, bridges, and CNI plugins — the networking foundation of containers.
Network Namespaces
Network namespaces isolate the network stack. Each namespace has its own interfaces, IP addresses, routing tables, firewall rules, and socket statistics. This is the foundation of container networking — each container gets its own network namespace.
# Create a network namespace
sudo ip netns add test-ns
# List namespaces
ip netns list
# test-ns
# Execute a command in the namespace
sudo ip netns exec test-ns ip addr
# 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN
# link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# Bring up loopback
sudo ip netns exec test-ns ip link set lo up
sudo ip netns exec test-ns ping -c 1 127.0.0.1
# PING 127.0.0.1: 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.041 msEach namespace has a completely isolated network stack. The loopback interface starts down and must be explicitly brought up.
veth Pairs
A veth (virtual Ethernet) pair is a tunnel — packets sent into one end come out the other. veth pairs connect namespaces to each other or to the host. One end goes into the container namespace, the other stays in the host.
# Create a veth pair
sudo ip link add veth0 type veth peer name veth1
# Move one end into a namespace
sudo ip link set veth1 netns test-ns
# Configure the host end
sudo ip addr add 10.0.0.1/24 dev veth0
sudo ip link set veth0 up
# Configure the namespace end
sudo ip netns exec test-ns ip addr add 10.0.0.2/24 dev veth1
sudo ip netns exec test-ns ip link set veth1 up
# Test connectivity
sudo ping -c 1 10.0.0.2
# PING 10.0.0.2: 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.089 msveth pairs are the standard way to connect containers to the host network. Kubernetes uses them for pod networking.
Linux Bridges
A Linux bridge acts as a virtual switch. Multiple veth pairs can connect to the same bridge, allowing containers to communicate. Docker uses docker0 bridge by default; Kubernetes uses cbr0 or a CNI-managed bridge.
# Create a bridge
sudo ip link add br0 type bridge
sudo ip addr add 192.168.100.1/24 dev br0
sudo ip link set br0 up
# Attach veth pairs to the bridge
sudo ip link set veth0 master br0
# Enable IP forwarding for routing
sysctl -w net.ipv4.ip_forward=1
# View bridge state
brctl show
# bridge name bridge id STP enabled interfaces
# br0 8000.123456789abc no veth0
# View forwarding table
bridge fdb show dev br0The bridge forwards frames between veth pairs like a physical switch. Enable STP (Spanning Tree Protocol) if you have complex bridge topologies to prevent loops.
Container Networking
Container runtimes (Docker, containerd) create a network namespace for each container, connect it via a veth pair to a bridge, and configure NAT for external access. Understanding this flow helps debug container networking issues.
# Docker creates a bridge and veth pairs automatically
docker network inspect bridge | head -20
# Inspect a container's network namespace
PID=$(docker inspect --format '{{.State.Pid}}' <container>)
nsenter -t $PID -n ip addr
# Or use docker exec
docker exec <container> ip addr
# Check veth pairs on the host
ip link show type veth
# veth1234@if2: <BROADCAST,MULTICAST,UP> ...
# Trace the path from container to host
docker exec <container> tracepath 192.168.100.1Docker creates a veth pair when a container starts. One end goes into the container namespace, the other is attached to docker0 bridge. NAT rules route external traffic.
CNI Plugins
CNI (Container Network Interface) is the Kubernetes standard for container networking. CNI plugins handle IP allocation, routing, and network policy. Each plugin has different characteristics for performance and features.
| Plugin | Approach | Best For |
|---|---|---|
| bridge | Linux bridge + veth | Simple single-node setups |
| calico | BGP routing | Large clusters, network policy |
| flannel | VXLAN overlay | Simple multi-node |
| cilium | eBPF | Performance, observability, policy |
| macvlan | Direct NIC access | Performance-critical workloads |
# Kubernetes CNI config
cat /etc/cni/net.d/*.conf
# {
# "cniVersion": "0.3.1",
# "type": "bridge",
# "bridge": "cbr0",
# "isGateway": true,
# "ipMasq": true,
# "ipam": { "type": "host-local" }
# }
# Check pod IP allocation
kubectl get pods -o wide | head -5
# NAME READY STATUS NODE IP NODE
# nginx-xxx 1/1 Running worker1 10.244.1.5 worker1CNI plugins are configured in /etc/cni/net.d/ on each node. Kubernetes calls the plugin when pods start to set up networking.
Managing Namespaces
# Delete a namespace
sudo ip netns delete test-ns
# Move an interface to a namespace
sudo ip link set eth0 netns <pid>
# View namespace processes
sudo ip netns pids test-ns
# 12345
# 12346
# Enter a namespace with ip netns exec
# This creates /var/run/netns/<name> for persistence
sudo ip netns attach test-ns <pid>
# Check namespace with nsenter
nsenter --net=/var/run/netns/test-ns ip addrip netns exec creates a named namespace if it does not exist. For unnamed namespaces, use nsenter with the PID directly.
nsenter -t <pid> -n enters a container's network namespace without creating a new one. This is useful for debugging container networking from the host.
Containers in separate network namespaces have isolated DNS resolution. If a container cannot resolve hostnames, check its /etc/resolv.conf and ensure DNS is configured correctly in the namespace.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.