Photo by Diego Fernandez on Unsplash

Linux Namespaces (part 5/5)

Docker & Lxc

Lukasz
5 min readSep 26, 2020

--

In the previous four parts I have described (more or less detailed) Linux Namespaces — now let’s practice more with docker and Lxc! If you have any docker container started in your system — check its PID:

e.g.:

Then we can check the NS identifiers used by the main process working in a container:

It’s worth to mention that in systems different than GNU/Linux docker will work in a virtual machine, so the process indicated by the command docker inspect will not be visible in your local system (host system) — because it is running in that virtual machine (hyperkit, hyperv or VirtualBox). If by chance there is a process with a given PID (in your system) — that’s for sure not the one we are looking for :). In MacOS, if you use hyperkit (used by default by Docker Desktop), we must connect to the console of this hypervisor in order to continue our example. We can do this e.g. by screen command:

(the path to the tty file/symlink can be different depending on the version of the Docker Desktop app, so if you can’t find it in the indicated location, please check its subdirectories).

In case of VirtualBox I think that it is much easier and everyone will deal with it :)

When we finally work in the console of the system in which the process of our container has been run, we should be able to find it on the processes list:

Then the command lsns -p PID should give us the result similar to the one below:

The interesting thing is that Docker does not use “cgroup” and “user Id” NS — in the list above we can see that these NS are inherited after the process init/systemd.

Now we can do the trickconnect to the console of this container thanks to nsenter command:

Where 4542 is obviously an appropriate PID indicated by the docker inspect command! Of course, the bash shell must be available in our container. The result generally should be identical to the one received after executing:

:)

In the case of Lxc the information on a given container can be acquired by the command:

After checking the NS (lsns -p PID) it will turn out that Lxc uses cgroups!

An interesting fact is also that process 9867 (so the main process of the Lxc container) is the init process. It results from the fact that Lxc delivers us the so-called system containers (which contains all the processes regularly started in real systems — that’s why Lxc is much more similar to the virtualization). Docker shares the so-called application containers (where there is no init process and the application itself is started with the PID 1).

Connecting to the Lxc container looks identical like in the Docker container case (notice the additional parameter “-C” meaning cgroups NS):

It works and I encourage you to carry out your own experiments!

Summary

I wrote in one of the previous parts that the tools like docker or Lxc can be considered as the high-level tools used for managing Linux Namespaces.The command nsenter lets us e.g. connect to any container in the way we can call low-level one. Of course, it is not the point, to encourage anyone to use nsenter in everyday work – it is not the case! It is only to give us more details about what happens under the hood :).

Another thing is that as in probably any case of reaching the lower levels in the technological stack also here we gain new possibilities! Using docker or Lxc we work only on defined NS groups (that we call containers) — for tools like nsenter/unshare the idea of container is unknown – here we work exclusively with namespaces. What can it mean? Let's imagine two containers:

And now let’s imagine (or test in practice) the effect of the following commands:

Where the process 3333 is running? In a new container which is using net and ipc NS from the container 1111 and mnt and utc NS from container 2222 (and the default pid NS)? Have we created a new container by mixing two others? An interesting result, isn’t it? :D

I wonder whether that idea of containers (in the way they are implemented by Lxc or docker) will last longer. Maybe soon we will stop using the abstract structures — containers — and start working directly with namespaces? It will surely demand breaking with the similarities to virtualization, but do we really need such connections? Probably the most important will be the users’ awareness — whether they will be interested in using Linux Namespaces directly ? It doesn’t look so (for the time being) and containers seem to be rather a long term solution, but — will see! :)

<< Linux Namespaces (part 4/5)

--

--