Linux Namespaces (part 3/5)
UTS stands for Unix Timesharing System, and NS itself is responsible for “isolating”… hostname (and NIS, but NIS itself has lost his meaning, I believe). It is worth noticing that both a page of man manual and the page in Wikipedia concerning NS do not mention the full name of UTS — so the full name, because of its “little” preciseness (as I suspect), is rather not used.
Let’s create a new UTS namespace:
$ sudo unshare -u
And for greater clarity of the description let’s look at PID, with which our new namespace is “connected”:
(unshare)$ echo $$
Namespace inherits the hostname after a parent, so:
should give us the same effect as in the superior NS UTS (so in our host system).
Now let’s change the hostname:
(unshare)$ hostname foo
hostname in this particular NS will show a new name if in a separate console we check the hostname for our host system (default UTS NS) we will see that it was not changed. Let’s pay our attention to the fact that the “command prompt” in our shell process with PID = 1234 (if “hostname” is visible there) – remains unchanged. But If in our shell with PID = 1234 we start another shell process:
The command prompt will contain an actual hostname for this NS: “foo”.
Also, if we use the command
nsenter for connecting another shell process to this namespace:
$ sudo nsenter -u -t 1234
the command prompt will contain a changed hostname — it’s just that bash (used here) does not update the hostname (in the command prompt) dynamically.
Namespace: Process ID (pid)
Both this one and the next NS (User ID) can be nested and in case of those two NS (PID and User ID) the process of mapping the identifier from superior NS (parent) on the identifier in secondary NS is conducted in the background.
Let’s look at a simple example:
$ sudo unshare -p -f
(unshare)$ echo $$
Pay attention to an additional parameter
-f of the command
unshare – it is used exclusively in connection with the parameter
-p and needed for correct functioning of the process in a newly created namespace (try to skip it and see what will happen at the moment of starting any command in namespace created in such a way) – a detailed explanation of why this parameter is required you can find e.g. here.
echo $$ (as we know) returns PID of started shell process – in this case PID = 1!
It seems that everything works fine, but when we execute the command
ps it turns out that we see many more processes than we could have expected! However it is the result of how the command
ps works – it does not take the information on processes from the current NS, but from the
/proc directory! So, from the point of view of
ps, nothing changes if in our secondary NS we use the same
/proc as in the superior NS (just like in this case).
How to correct this? Let’s use an additional namespace — mnt — and the already tested
$ sudo unshare -p -f -m chroot /directory
(unshare)# mount -t proc proc /proc
(unshare)# echo $$
(unshare)# ps ax
PID TTY STAT TIME COMMAND
1 ? S 0:00 /bin/bash -i
4 ? R+ 0:00 ps ax
Now it is just as it should be! :)
Let’s look at an example of another nesting:
(unshare pid + chroot)# unshare -p -f
(1) mesg: ttyname failed: No such file or directory
(unshare pid + chroot)# echo $$
(unshare pid + chroot)# ps axf
(3) PID TTY STAT TIME COMMAND
1 ? S 0:00 /bin/bash -i
5 ? S 0:00 unshare -p -f
6 ? S 0:00 \_ -bash
11 ? R+ 0:00 \_ ps axf
So in our unshared-and-chrooted environment we create another nesting of PID NS — we can see an error message (1) that can be ignored. (2) A new shell process created in new PID NS has PID = 1 (which is shown by
echo command), however the command
ps (that we tested) identified this process by the identifier attributed to it in the
/proc directory – here as the process with PID = 6 (3).
At the end let’s try to “connect” (using
nsenter) to PID NS created by the first (from the previous example) command
unshare – first we need to determine PID of the shell process started in this NS:
$ sudo lsns
4026532455 mnt 4 27902 root unshare -m -f -p chroot FS_AA
4026532456 pid 2 27903 root /bin/bash -i
So PID that interests us is 27903 — now let’s try:
$ sudo nsenter -p -t 27903
(nsenter)# echo $$
nsenter command starts a NEW shell process, that’s why its PID does not equal "1" anymore, but it is still PID that makes sense only in PID NS of the process 27903.
Namespace: User ID (user)
Here I recommend doing your own experiments. The functioning of this NS is similar to PID NS, here we also deal with a possible nesting. Docker and Lxc seem not to use this NS (at least in environments which I had an opportunity to work with).
Namespace: Interprocess Communication (ipc)
NS that let us isolate the system (Linux) structures for inter-process communication (semaphores) — until now I haven’t had an opportunity to use it, so I have no experience in this field — it definitely needs further exploration. :)