Docker Container Network Namespace Is Invisible


This article will look at a problem with the network namespace file in a Docker container. We'll examine why the network namespace file is invisible to the ip netns ls command.

Before moving ahead, let's have a brief overview of Docker, Containers and Network Namespace

Containerization

Containerization is similar to virtualization, in which an application and all its dependencies and libraries are packaged into a single container; it can run in any computing environment. When the OS kernel and all necessary libraries and dependencies are included in the container, anyone working on the application can use only the container to work on it rather than setting up the appropriate computing environment on a virtual machine. Containers have no guest operating system and run the hosts. As a result, they share relevant libraries and resources as needed.

Because container-specific binaries and libraries run on the host kernel, application processing and execution are extremely fast.

A container boots up in a fraction of a second, and containers are lighter and faster than Virtual Machines.

Docker

Docker is a software platform that enables rapid development, testing, and deployment of applications. Docker organises software into standardised units called containers, which contain everything the software requires to run, such as libraries, system tools, code, and runtime. Docker allows you to quickly deploy and scale applications into any environment while remaining confident that your code will run.

Network Namespaces

Linux network namespaces are a kernel feature that allows us to virtualize and isolate network environments. Using network namespaces, for example, you can create independent network interfaces and routing tables that are separated from the rest of the system.

Namespaces in Linux are classified into six types: pid, net, uts, mnt, ipc, and user.

Example

If you run the command “lsns”, it will display all of your system's existing namespaces, as shown below.

$ lsns

Output

 NS TYPE NPROCS PID USER COMMAND
4026531836 pid 2 7358 sachin -bash
4026531837 user 2 7358 sachin -bash
4026531838 uts 2 7358 sachin -bash
4026531839 ipc 2 7358 sachin -bash
4026531840 mnt 2 7358 sachin -bash
4026532185 net 2 7358 sachin -bash

Invisible Docker Network Namespace

When we create a Docker container, the daemon will generate the namespaces pseudo files for the container process. These files will then be placed in the directory /proc/pid/ns, where pid is the container's process ID. Consider the following scenario:

pi@TTP:sudo docker run --rm -d ubuntu:latest sleep infinity
c5503724a3ab4339e9246f0ef4cddf475e1f4f98964df834bfacaf5ff1
70fb03
pi@TTP:docker inspect --format '{{.State.Pid}}' c5503724a3ab
1946

Looking into the /proc/1946/ns directory, we can see that all of the various types of namespaces have been created.

pi@TTP:sudo ls -la /proc/1946/ns
total 0
dr-x--x--x 2 root root 0 Oct 6 17:25 .
dr-xr-xr-x 9 root root 0 Oct 6 17:25 ..
lrwxrwxrwx 1 root root 0 Oct 6 17:28 ipc -> ipc:[4026532177]
lrwxrwxrwx 1 root root 0 Oct 6 17:25 mnt -> mnt:[4026532175]
lrwxrwxrwx 1 root root 0 Oct 6 17:25 net -> net:[4026532180]
lrwxrwxrwx 1 root root 0 Oct 6 17:28 pid -> pid:[4026532178]
lrwxrwxrwx 1 root root 0 Oct 6 17:28 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Oct 6 17:28 uts -> uts:[4026532176]

The presence of the net file for this process can be seen in the list of namespace pseudo files. We can expect the net file to appear when we list all network namespaces because it corresponds to a Linux network namespace. However, it is clear that this is not the case. Running ip netns ls now, for example, yields 0 results.

pi@TTP:ip netns ls
pi@TTP:

Missing File Reference

We must understand that the ip netns ls command searches the network namespaces file in the /var/run/netns directory. However, after the network namespace file is created, the Docker daemon does not create a reference to it in the /var/run/netns directory. As a result, ip netns ls is unable to resolve the network namespace file.

pi@TTP:mkdir -p /var/run/netns
pi@TTP:touch /var/run/netns/c5503724a3ab

To bind mount the net file, use the mount -o bind command −

pi@TTP:mount -o bind /proc/1946/ns/net
/var/run/netns/c5503724a3ab

Running the same ip netns ls command again would, as expected, display the network namespace.

pi@TTP:ip netns ls
c5503724a3ab (id: 1)

After establishing a file reference to the network namespace file, we can use ip netns exec to execute any ip commands. For example, we can use the ip addr list command to examine the interfaces in the network namespace −

pi@TTP:ip netns exec c5503724a3ab ip addr list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu
1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link
       valid_lft forever preferred_lft forever

Conclusion

We began this tutorial with a quick overview of Linux namespaces, Docker and Conatiners. Then, we demonstrated the issue in which the network namespace file created by docker run does not appear when we run ip netns ls. We later discovered that this is because the file reference is not made at /var/run/netns, which is where the ip netns ls command looks for any network namespaces.

Finally, we concluded the article with a simple fix: bind mount the file to /var/run/netns so it can be found with ip netns ls.

Updated on: 21-Nov-2022

512 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements