WSS
On this page
Containers & OrchestrationRequiredUpdated

Network namespaces and isolation

The Linux kernel features that provide containers with their own independent network stacks, interfaces, and routing tables.

What it is

A container is not a virtual machine. It does not have its own operating system kernel. Instead, a container is just a normal Linux process that is lied to by the host operating system. The primary mechanism for this deception is the Linux Namespace.

A Network Namespace (netns) provides a process with a completely isolated network stack. When a process is placed inside a new network namespace, it cannot see the host’s physical network interfaces (like eth0), it has its own independent routing table, its own iptables firewall rules, and its own loopback interface (lo).

Why it matters

Without network namespaces, multiple processes running on the same physical server share the same network stack. If two different web servers both attempt to bind to port 80, the second one will crash with a “port already in use” error.

Network namespaces solve this. By giving each container its own namespace, every container has its own port 80. They are completely isolated from the host and from each other, allowing for massive density and avoiding port collisions. This isolation is the foundational building block of all modern container networking, including Docker and Kubernetes.

How to implement

While container runtimes handle this automatically, understanding the underlying mechanism is critical for deep debugging.

  1. Creation: The runtime creates a new namespace using the unshare system call. The container process now sees an empty network - it has no interfaces and no connection to the outside world.
  2. Virtual Ethernet (veth): The runtime creates a pair of virtual ethernet cables (veth pair). Think of this as a virtual wire with two ends.
  3. Plugging In: The runtime plugs one end of the veth pair into the container’s network namespace (often renaming it to eth0 inside the container). It leaves the other end plugged into the host’s default network namespace.
  4. Routing: The host acts as a virtual switch (bridge). When the container sends a packet out its eth0 interface, the packet travels across the veth pair to the host. The host’s routing table then forwards it to the physical network or to another container.

Common mistakes

Assuming Complete Security Isolation

While namespaces isolate network visibility, they do not inherently block traffic. If two containers are connected to the same virtual bridge on the host, they can ping each other and access each other’s open ports unless the host explicitly drops those packets using firewall rules (like Kubernetes NetworkPolicies). Namespaces provide logical isolation, not cryptographic security.

Debugging the Wrong Namespace

When a container cannot reach a database, an operator might SSH into the physical host node and run ping database.internal. If the ping succeeds, the operator incorrectly assumes the network is fine. The host’s default namespace has different routing rules, DNS settings, and firewall policies than the container’s namespace. Diagnostics must always be run from within the container’s specific network namespace.

Overlooking the Loopback Interface

When a new network namespace is created, its loopback interface (lo) is down by default. If the container runtime fails to explicitly bring it up (ip link set lo up), processes inside the container attempting to bind to localhost or 127.0.0.1 will fail mysteriously, even though external networking works perfectly.

Verification

To verify network namespaces directly on a Linux host (bypassing Docker/Kubernetes), use the ip command suite.

List the existing network namespaces on the host:

ip netns list

Create a brand new, isolated network namespace named “isolated”:

ip netns add isolated

Execute a command inside that specific namespace to see its perspective. Notice it only has a loopback interface, and it is DOWN:

ip netns exec isolated ip link list

In a Kubernetes environment, to execute a network diagnostic tool inside a Pod’s namespace, use kubectl exec:

kubectl exec -it web-pod -- ip route list

This shows the routing table exactly as the application process sees it, completely independent of the host node’s routing table.

Related topics

Sources & further reading