Cloud Native 28 min read

Master Single-Host Container Networking with Linux Namespaces, veth, and Bridges

Learn how to virtualize network resources on a single Linux host using network namespaces, virtual Ethernet devices, bridges, and NAT, enabling isolated containers to communicate with each other, the host, and the external internet without complex code, while covering setup, routing, and port publishing.

Efficient Ops
Efficient Ops
Efficient Ops
Master Single-Host Container Networking with Linux Namespaces, veth, and Bridges

Using containers often feels like magic; for those who understand the underlying principles, containers are powerful, but for others they can be a nightmare. This guide demystifies single‑host container networking by explaining how to virtualize network resources so containers think they have exclusive networks, can communicate without interference, and can reach both the host and the external world.

Prerequisites

Any Linux distribution works. All examples were run on a Vagrant CentOS 8 VM.

<code>$ vagrant init centos/8
$ vagrant up
$ vagrant ssh
[vagrant@localhost ~]$ uname -a
Linux localhost.localdomain 4.18.0-147.3.1.el8_1.x86_64</code>

Inspecting the network stack

Create a simple script to list devices, routes, and iptables rules.

<code>#!/usr/bin/env bash

echo "> Network devices"
ip link

echo -e "\n> Route table"
ip route

echo -e "\n> Iptables rules"
iptables --list-rules</code>

Run the script after adding a custom iptables chain:

<code>$ sudo iptables -N ROOT_NS</code>

The output shows separate network stacks for the host and any namespace.

Network namespace isolation

Create a network namespace:

<code>$ sudo ip netns add netns0
$ ip netns list
netns0</code>

Enter the namespace with

nsenter

and verify the isolated stack:

<code>$ sudo nsenter --net=/var/run/netns/netns0 bash
# inside netns0
$ ip link
# shows only lo</code>

Connecting containers with virtual Ethernet (veth)

Create a paired veth pair and move one end into the namespace:

<code>$ sudo ip link add veth0 type veth peer name ceth0
$ sudo ip link set ceth0 netns netns0
$ sudo ip link set veth0 up</code>

Assign IP addresses:

<code>$ sudo ip addr add 172.18.0.11/16 dev veth0
$ sudo nsenter --net=/var/run/netns/netns0 bash -c "ip addr add 172.18.0.10/16 dev ceth0 && ip link set lo up && ip link set ceth0 up"</code>

Ping between the two ends to confirm L2 connectivity.

Using a Linux bridge for multiple containers

When multiple containers share the same IP subnet, a bridge (virtual switch) solves routing conflicts.

<code>$ sudo ip link add br0 type bridge
$ sudo ip link set br0 up
$ sudo ip link set veth0 master br0
$ sudo ip link set veth1 master br0</code>

After attaching both veth pairs to

br0

, containers can ping each other across namespaces.

Connecting the bridge to the host and the external world

Assign an IP to the bridge interface:

<code>$ sudo ip addr add 172.18.0.1/16 dev br0</code>

Add a default route inside each container pointing to the bridge:

<code>$ sudo nsenter --net=/var/run/netns/netns0 bash -c "ip route add default via 172.18.0.1"
$ sudo nsenter --net=/var/run/netns/netns1 bash -c "ip route add default via 172.18.0.1"</code>

Enable IP forwarding on the host:

<code>sudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'</code>

Apply NAT (masquerading) so containers can reach the internet:

<code>sudo iptables -t nat -A POSTROUTING -s 172.18.0.0/16 ! -o br0 -j MASQUERADE</code>

Now containers can ping external addresses such as 8.8.8.8.

Port publishing

Run a service inside a container (e.g., a simple HTTP server) and access it from the host using the container’s IP. To expose it externally, publish the host’s IP and port, which is effectively handled by the NAT rule above.

Docker network drivers

Docker’s built‑in drivers correspond to the modes demonstrated:

host : no network namespace isolation.

none : only a loopback interface.

bridge (default): uses a Linux bridge similar to the manual setup.

Rootless containers

Rootless containers (e.g., Podman with

slirp4netns

) cannot manipulate host network devices directly, so they rely on user‑space networking. They lack raw socket capabilities, making tools like

ping

unavailable without extra privileges.

Conclusion

The presented approach—network namespaces, veth pairs, a Linux bridge, routing, and NAT—covers a widely used method for single‑host container networking. While many other solutions and plugins exist, they all build on the same Linux virtual networking primitives.

NATBridgeiptablesContainer NetworkingLinux namespacesVeth
Efficient Ops
Written by

Efficient Ops

This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.