What is a Network Namespace?

Network namespaces allow you to have isolated network environments on a single host.

Each namespace has its own interfaces and routing table, separated from other namespaces. In addition, processes on your system can be associated with a specific network namespace.

Network namespace used in a variety of projects such as OpenStack, Docker and Mininet. To deep dive into these projects, you’ll have to be familiar with namespaces and know how to work with them.

Working with network namespaces

When starting Linux, you’ll have one namespace on your system and every new created process will inherit this namespace from its  parent. So, all the processes inherit the network namespace used by init (PID 1).

List namespaces

The way to work with namespaces is by using the ‘ip netns’ command (man ip-netns).

To list all the network namespace on your system, use ‘ip netns’ or ‘ip netns list’

If you haven’t added any namespace, the output will be empty. The default namespace is not included in  ‘ip netns list’ output.

Add namespaces

To add a namespace, use the ‘ip netns add <name>’ command.  Let’s give it a try.

We created two namespaces. One called ‘mario’ and the other called ‘luigi’.

namespace_level2

 

As you can see in the drawing, the new namespaces we just created, separate from the system default namespace.

To ensure they have been created, you can use the ‘ip netns list’ command, as mentioned earlier.

Once a namespace is added, a new file created in ‘/var/run/netns’ with the same name as the namespace. In our case, there should be two files there, one for each namespace we created (again, not including the default namespace).

Executing commands in namespaces

To execute commands in a namespace (which is not the ‘default’ namespace) use ‘ip netns exec <namespace> <command>’

In the above example, we ran the command ‘ip a’ in the namespace ‘mario’. This should give a different result than running it in the default namespace, as each namespace is an isolated environment with its own interfaces and routing table.

It is possible to run a specific command on all existing namespaces using the ‘-all’ flag

Assign network interface to a specific namespace

This is basically moving interfaces from the default namespace to the namespace you specify

Let’s say you have on your default namespace, a network device which called ‘toad’.

If you want to set ‘toad’ on your namespace ‘x’ rather than on the default namespace, you can use the ‘ip link set’ command.

Ping between two namespaces

Let’s take a simple scenario in which we will emulate two nodes (each namespace will represent a node). We’ll connect the two namespaces to a virtual switch and send a ping from one namespace to another.

Add virtual switch

For a virtual switch, I’ll use OpenvSwitch and I’ll create the switch in the default namespace.

But first, let’s install OpenvSwitch and start its service.

Next, let’s add a new virtual switch. I called it ‘my_switch’ (yes, creativity level over 1000)

Verify it was added

To connect the namespaces to our switch, we’ll use ‘veth’ pairs. Since there is not much documentation on ‘veth’, let’s take a minute to explain what is ‘veth’.


veth

veth (Virtual Ethernet) is a type of network device which always comes in pairs. You can imagine this pair as a tube. Everything you’ll send through one end of the  tube, will come out  at the other end.

You can see it always comes in a pair, by adding such device in your system

As you can see, there are two devices which compose the pair.  Sending anything through veth0@veth1, would come out through veth1@veth0.

Now, remove it, since we don’t need it as it is now, for our example

Removing one of them, would also remove the other peer as they always come in pairs.


Creating veth devices

Now back to connecting the namespaces to our virtual switch.

Let’s create veth device to connect ‘mario’ namespace to the virtual switch.

This is slightly different than what you saw earlier. Here I specified the name for each end/member of the pair. So mario-netns will be in ‘mario’ namespace and ‘mario-ovs’  will connect to our virtual switch.

Let’s verify it’s been created

Now let’s set ‘mario-netns’ in ‘mario’ namespace

Remember we said that namespace is an isolated network environment and ‘default’ namespace is separated from other namespaces? If that’s true, you should not see ‘mario-netns’ anymore in the ‘default’ namespace, since we put it in ‘mario’ namespace

As you can see ‘mario-netns’ is now in ‘mario’ namespace. That is why you can’t see it in the default namespace.

Now let’s add the other end (mario-ovs) to our virtual switch.

We can see in the above output that ‘mario-ovs’ is now a port in ‘my_switch’, after we added it with the ‘ovs-vsctl add-port’ command.

Let’s do the same for ‘luigi’ namespace, but this time, all the commands one after another.

What we achieved so far? we created veth pair for each one of our namespaces. So on ‘my_switch’ we have two ports, one for each namespace and in each namespace we have the other end of the veth pair.

This how it should look (and please accuse me for my (virtual) drawing skills 🙂 )

gil-1

Does it mean that we can now reach from ‘mario’ namespace to ‘luigi’ namespace? not yet. It might sound basic, but we need to assign addresses to our devices and bring them up 😀

Bringing up our devices

First, let’s bring up our devices in the ‘default’ namespace

Now, let’s bring up all the devices in ‘mario’ and ‘luigi’ namespaces

Assign addresses

Next, we should assign addresses for both ‘mario-netns’ and ‘luigi-netns’ devices in the namespces

We can verify the devices are up and assigned with IP address

Ping test

That’s it. Our namespaces connected to the switch, the devices are up with an assigned IP address and we are ready for our ping test.

Let’s ping from ‘mario’ namespace to ‘luigi’ namespace

Amazing, it’s working 😀

Commands reference

Before saying goodbye, I gathered all the commands we used in this post, for an easier reference:

Q & A

Q: How can I work fluently inside a namepsace, without using ‘ip netns exec’ for each command?

A: You can use ‘ip netns exec <ns_name> bash’ which will spawn a shell where you’ll be able to work inside a specific namespace.

Q: Are you a fan of Nintendo? You are using the name ‘mario’ in a lot of your posts

A: Yes. Proud fan since 1994 🙂