Skip to main content
In this lesson we introduce Linux network namespaces — the fundamental building blocks that provide network isolation for containers (for example, Docker containers — see Docker Training Course for the Absolute Beginner). We start with the host and progressively build namespaces, connect them with virtual links, and enable external access using routing and NAT. If your host is a house, namespaces are the rooms you assign to each child. A room provides privacy: each child sees only what is inside their room and thinks they are the only person in the house. The parent (the host) still has visibility into all rooms and the rest of the house.
A dark slide titled "Namespaces" showing a house-shaped container with colorful rounded-square user icons and a larger white person icon standing on a pedestal inside. The image has a deep blue background and a small "© Copyright KodeKloud" label in the corner.
When you create a container, the runtime creates a network namespace for it. Inside that namespace the container sees only the processes and network devices assigned to it and behaves as if it runs on a private host. The underlying host still sees all processes and interfaces. Example: process list inside a container versus on the host Inside the container:
Same process from the host (PID differs and appears among other host processes):
Network namespaces also separate interfaces, ARP tables, and routing tables. The host keeps its own network stack (interfaces, routes, ARP), while each namespace can have independent virtual interfaces, ARP entries, and routing.
A diagram titled "Network Namespace" showing a host with an eth0 interface (192.168.1.2) linked to a LAN cloud labeled 192.168.1.0, with routing and ARP tables depicted at the host.
Network namespaces, veth pairs, moving interfaces, and iptables changes require root privileges. Prepend sudo to commands or run as root.

Create and inspect namespaces

Create namespaces and inspect them using ip:
Run commands inside a namespace using ip netns exec or ip -n:
Typical output:
Note how red only shows the loopback interface; it cannot see the host’s eth0. Each namespace maintains its own ARP (arp -n) and routing table (ip route).

Virtual Ethernet pairs (veth) — connect two namespaces

A veth pair acts like a virtual cable with two ends. To directly connect two namespaces:
Assign IPs and bring interfaces up inside each namespace:
Test connectivity:
Check ARP tables inside namespaces:
The host ARP table does not include these entries because the veth interfaces are private to namespaces.

From point-to-point to a virtual network: Linux bridge

Direct veth pairs are fine for two endpoints. To connect multiple namespaces to the same Layer 2 network, create a Linux bridge on the host and attach each namespace via a veth peer.
A stylized network diagram showing a Linux bridge linking virtual Ethernet interfaces (veth-red at 192.168.15.1 and veth-blue at 192.168.15.2) on the 192.168.15.0 network, with an eth0 connection.
Create and enable the bridge on the host:
If you created a direct veth pair earlier and want to switch to a bridged network, delete the direct pair (note: deleting one end removes both):
Create veth pairs for each namespace where one side stays in the namespace and the other attaches to the bridge:
Inside each namespace, assign IPs and bring interfaces up:
All namespaces connected to v-net-0 can communicate at Layer 2 through the bridge.

Host access to the bridge network

The bridge is a host interface. Assign an IP address to the bridge so the host can reach the namespace network:
Without an IP on v-net-0, the host cannot reach 192.168.15.x addresses. After assigning 192.168.15.5/24, the host can communicate with namespaces:

Allowing namespaces to reach external networks (routing + NAT)

Namespaces on the bridge can talk to each other and the host, but they cannot reach the external LAN or internet until you provide routing and NAT. Example scenario:
  • Host external interface: eth0 = 192.168.1.2
  • Bridge interface: v-net-0 = 192.168.15.5
  • Namespace blue = 192.168.15.2
Add a route inside the namespace so it uses the host as a gateway:
Enable IP forwarding on the host:
Set up NAT (masquerading) so replies from the external network are correctly routed back through the host:
Now namespaces can reach external IPs:

Exposing a service running in a namespace to the LAN

Two common approaches to make a namespace service reachable from other hosts on the LAN:
  1. Add routing on remote hosts so they know the private network is reachable via your host (often impractical).
  2. Use port forwarding (DNAT) on the host to map a host port to the namespace IP:port.
Example: forward host TCP port 80 to blue namespace port 80 and also apply masquerade:
Also ensure the filter table allows forwarding and the FORWARD chain accepts the forwarded packets as needed.
Deleting one end of a veth pair removes both ends. Be careful when deleting interfaces and ensure important iptables rules are saved if you want persistence across reboots.

Quick reference — common commands

That’s it for this lesson — you now know how to create network namespaces, connect them with veth pairs and bridges, enable host access, and expose namespace services to the outside world.

Watch Video