There are many different types of Linux namespaces - Cgroup, IPC, Mount, PID, User, UTS, Network.

Let’s look at the Network one.

It’s kind of like having a container with its own isolated virtual network.

Let’s create 2.

$ sudo ip netns add my_container_a

$ sudo ip netns add my_container_b

$ ip netns list
my_container_b
my_container_a


Then you can kind of spawn a shell inside it.

You’ll notice networking is not set up, it can’t even ping localhost.

$ sudo ip netns exec my_container_a bash

# ping 127.0.0.1
ping: connect: Network is unreachable

# 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



Now let’s connect my_container_a to my_container_b.

We use the veth interface, which is like a virtual ethernet cable.


[ my_container_a ] my_veth_end_a <==== virtual cable ==== > my_veth_end_b [ my_container_b ]


We actually create the 2 ends of the cable at once.

$ sudo ip link add my_veth_end_a type veth peer name my_veth_end_b


Next we ‘plug in’ each end of the cable:

$ sudo ip link set my_veth_end_a netns my_container_a
$ sudo ip link set my_veth_end_b netns my_container_b


And should now be able to see it from within the container:

# 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
5: my_veth_end_a@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 96:1a:bf:cf:64:ce brd ff:ff:ff:ff:ff:ff link-netns my_container_b


Then you can assign IPs, I’ll give a 10.0.0.1 and b 10.0.0.2:

$ sudo ip netns exec my_container_a ip addr add "10.0.0.1/24" dev my_veth_end_a
$ sudo ip netns exec my_container_b ip addr add "10.0.0.2/24" dev my_veth_end_b
# 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
5: my_veth_end_a@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 96:1a:bf:cf:64:ce brd ff:ff:ff:ff:ff:ff link-netns my_container_b
    inet 10.0.0.1/24 scope global my_veth_end_a
       valid_lft forever preferred_lft forever


We can see the IP now but it still says state DOWN. Once the IPs are assigned, bring them to UP state:

Note we can bring one up:

$ sudo ip netns exec my_container_a ip link set my_veth_end_a up

And try ping the other but get no reply:

# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.

Then bring the other up:

$ sudo ip netns exec my_container_b ip link set my_veth_end_b up

And now both should be able to ping each other!!



Cleanup:

sudo ip netns del my_container_a 
sudo ip netns del my_container_b





One script combining all of the above:

# create network namespaces
sudo ip netns add my_container_a
sudo ip netns add my_container_b

# create virtual ethernet cable
sudo ip link add my_veth_end_a type veth peer name my_veth_end_b

# 'plug in' each end of the cable
sudo ip link set my_veth_end_a netns my_container_a
sudo ip link set my_veth_end_b netns my_container_b

# assign IPs
sudo ip netns exec my_container_a ip addr add "10.0.0.1/24" dev my_veth_end_a
sudo ip netns exec my_container_b ip addr add "10.0.0.2/24" dev my_veth_end_b

# bring to UP state
sudo ip netns exec my_container_a ip link set my_veth_end_a up
sudo ip netns exec my_container_b ip link set my_veth_end_b up



# access networks namespaces
# sudo ip netns exec my_container_a bash
# sudo ip netns exec my_container_b bash