Container Networking Under The Hood: Network Namespaces

Photo by Jordan Harrison on Unsplash

Virtual Ethernet Device

Let’s assume that you have two computers. You probably know you can create a network link between those two computers via an ethernet cable, and you don’t need a network switch for that.

ip netns add pc-one
ip netns add pc-two
ip link add veth-pc-one type veth peer name veth-pc-two
ip link set veth-pc-one netns pc-one
ip link set veth-pc-two netns pc-two
root@adil:~# ip netns exec pc-one ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: veth-pc-one@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 8e:ef:69:a1:a3:93 brd ff:ff:ff:ff:ff:ff link-netns pc-two
ip netns exec pc-one ip link set dev veth-pc-one up
ip netns exec pc-two ip link set dev veth-pc-two up
ip netns exec pc-one ip link set dev lo up
ip netns exec pc-two ip link set dev lo up
ip -n pc-one addr add 10.0.0.1/24 dev veth-pc-one
ip -n pc-two addr add 10.0.0.2/24 dev veth-pc-two
root@adil:~# ip netns exec pc-one ping 10.0.0.1 -c1
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.020 ms
root@adil:~# ip netns exec pc-one ping 10.0.0.2 -c1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.022 ms
root@adil:~# ip netns exec pc-two ping 10.0.0.1 -c1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.037 ms
root@adil:~# ip netns exec pc-two ping 10.0.0.2 -c1
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.018 ms
root@adil:~# ip netns exec pc-one ip route
10.0.0.0/24 dev veth-pc-one proto kernel scope link src 10.0.0.1
root@adil:~# ping 10.0.0.1 -c1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

Virtual Bridge

We have created a network link between 2 network namespaces. What if you need to connect 3+ network namespaces?

ip netns add one
ip netns add two
ip netns add three
ip link add veth-one-in type veth peer name veth-one-out
ip link add veth-two-in type veth peer name veth-two-out
ip link add veth-three-in type veth peer name veth-three-out
ip link set veth-one-in   netns one
ip link set veth-two-in netns two
ip link set veth-three-in netns three
ip netns exec one ip addr add 10.0.0.10/24 dev veth-one-in
ip netns exec two ip addr add 10.0.0.20/24 dev veth-two-in
ip netns exec three ip addr add 10.0.0.30/24 dev veth-three-in
ip link add name virtual-bridge type bridge
ip link set veth-one-out   master virtual-bridge
ip link set veth-two-out master virtual-bridge
ip link set veth-three-out master virtual-bridge
ip link set virtual-bridge upip link set veth-one-out   up
ip link set veth-two-out up
ip link set veth-three-out up
ip netns exec one ip link set dev veth-one-in up
ip netns exec two ip link set dev veth-two-in up
ip netns exec three ip link set dev veth-three-in up
ip netns exec one ip link set dev lo up
ip netns exec two ip link set dev lo up
ip netns exec three ip link set dev lo up
root@adil:~# ip netns exec one ping 10.0.0.10 -c1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.017 ms
root@adil:~# ip netns exec one ping 10.0.0.20 -c1
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.052 ms
root@adil:~# ip netns exec one ping 10.0.0.30 -c1
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.051 ms
root@adil:~# ping 10.0.0.10 -c1
PING 10.0.0.10 (10.0.0.10) 56(84) bytes of data.
— — 10.0.0.10 ping statistics — -
1 packets transmitted, 0 received, 100% packet loss, time 0ms
ip addr add 10.0.0.1/24 dev virtual-bridge
root@adil:~# ping 10.0.0.10 -c1
PING 10.0.0.10 (10.0.0.10) 56(84) bytes of data.
64 bytes from 10.0.0.10: icmp_seq=1 ttl=64 time=0.065 ms

Can the network namespaces connect to Internet?

root@adil:~# ip netns exec three ping 8.8.8.8
ping: connect: Network is unreachable
ip netns exec one ip route add default via 10.0.0.1
ip netns exec two ip route add default via 10.0.0.1
ip netns exec three ip route add default via 10.0.0.1
root@adil:~# ip netns exec three ping 8.8.8.8
ping: connect: Network is unreachable
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
sysctl -w net.ipv4.ip_forward=1
root@adil:~# ip netns exec three ping 8.8.8.8 -c1
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=111 time=0.818 ms

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store