Introduction

In a previous post, we talked about how kernel namespaces and cgroups form the building blocks of containerization in Linux. In this article, we will explore namespaces in more depth by demonstrating some examples of creating namespaces using the unshare command.
Namespaces use the clone(), unshare() and netns() system calls to allow different process hierarchies to have different views of the underlying operating system resources.

  • The clone() system call creates a new process and attaches it to a new specified namespace
  • The unshare() system call attaches the current process to a new specified namespace
  • The setns() system call attaches a process to an already existing namespace

We will now explore the creation of mount and UTS namespaces to illustrate how a process can have a different file system hierarchy and hostname as compared to the rest of the system. Since we will be using the unshare command to create our namespaces, we’d like to share an excerpt from its man page explaining its usage.

NAME
unshare - run program with some namespaces unshared from parent



SYNOPSIS
unshare [options] program [arguments]



DESCRIPTION
Unshares the indicated namespaces from the parent process and then executes the specified program. The namespaces to be unshared are indicated via options.
Unshareable namespaces are:



mount namespace Mounting and unmounting filesystems will not affect the rest of the system (CLONE_NEWNS flag), except for filesystems which are explicitly marked as shared (with mount --make-shared; see /proc/self/mountinfo or findmnt -o+PROPAGATION for the shared flags). unshare automatically sets propagation to private in the new mount namespace to make sure that the new namespace is really unshared. This feature is possible to disable by option --propagation unchanged. Note that private is the kernel default. UTS namespace Setting hostname or domainname will not affect the rest of the system. (CLONE_NEWUTS flag) IPC namespace The process will have an independent namespace for System V message queues, semaphore sets and shared memory segments. (CLONE_NEWIPC flag) network namespace The process will have independent IPv4 and IPv6 stacks, IP routing tables, firewall rules, the /proc/net and /sys/class/net directory trees, sockets, etc. (CLONE_NEWNET flag) pid namespace Children will have a distinct set of PID to process mappings from their parent. (CLONE_NEWPID flag) user namespace The process will have a distinct set of UIDs, GIDs and capabilities. (CLONE_NEWUSER flag)

As you may have observed from the above snippet, the man page mentions a brief description of the different namespaces that can be created using the unshare command. The util-linux package provides userspace tools that implement the unshare() call, which effectively unshares the indicated namespaces from the parent process.

Creating a new mount namespace:

Step 1: Create a new directory within /tmp

[root@linuxnix ~]# mkdir /tmp/mount_namespace
[root@linuxnix ~]#

Step 2: Next, move the current bash process to its own mount namespace by passing the mount flag to the unshare command as shown below

[root@linuxnix ~]# unshare -m /bin/bash
[root@linuxnix ~]#

Step 3: The bash process is now in a separate namespace. Let’s check the associated inode number of the namespace

[root@linuxnix ~]# readlink /proc/$/ns/mnt
mnt:[4026532169]

Step 4: Create a temporary mount point and verify that it’s accessible

[root@linuxnix ~]# mount -n -t tmpfs tmpfs /tmp/mount_namespace
[root@linuxnix ~]# df -hTP /tmp/mount_namespace
Filesystem Type Size Used Avail Use% Mounted on
tmpfs tmpfs 484M 0 484M 0% /tmp/mount_namespace
[root@linuxnix ~]# cat /proc/mounts | grep /tmp/mount_namespace
tmpfs /tmp/mount_namespace tmpfs rw,seclabel,relatime 0 0
[root@linuxnix ~]#

Step 5: Now, start a new terminal session and display the namespace inode ID from it:

[root@linuxnix ~]# readlink /proc/$/ns/mnt
mnt:[4026531840]
[root@linuxnix ~]#

Notice that this value is different from the one in the other terminal.

Step 6: Let’s check if the mount point is visible in the new terminal session

[root@linuxnix ~]# df -hTP /tmp/mount_namespace
Filesystem Type Size Used Avail Use% Mounted on
/dev/nvme0n1p1 xfs 20G 7.1G 13G 36% /
[root@linuxnix ~]# cat /proc/mounts | grep /tmp/mount_namespace
[root@linuxnix ~]#

As expected the mount point is not visible in the default namespace. In the context of LXC, mount namespaces are useful because they provide a way for a different filesystem layout to exist inside the container.

 

Creating a UTS namespace

Unix Timesharing (UTS) namespaces provide isolation for the hostname and domain name, so that each LXC container can maintain its own identifier as returned by the hostname -f command. This is needed for most applications that rely on a properly set hostname. To create a bash session in a new UTS namespace, we can use the unshare utility again, which uses the unshare() system call to create the namespace and the execve() system call to execute bash in it:

[root@linuxnix ~]# hostname
linuxnix
[root@linuxnix ~]# unshare -u /bin/bash
[root@linuxnix ~]# hostname uts
[root@linuxnix ~]# hostname
uts
[root@linuxnix ~]# cat /proc/sys/kernel/hostname
uts

Next, from a different terminal, check the hostname again to make sure it has not changed.

[root@linuxnix ~]# hostname
linuxnix
[root@linuxnix ~]#

As expected, the hostname only changed in the new UTS namespace.

 

Conclusion

This concludes our slightly more detailed look at how namespaces in Linux allow different processes hierarchies to view allowed system resources only. We hope that you found this post to be helpful and we look forward to your suggestions and feedback.

The following two tabs change content below.

Sahil Suri

He started his career in IT in 2011 as a system administrator. He has since worked with HP-UX, Solaris and Linux operating systems along with exposure to high availability and virtualization solutions. He has a keen interest in shell, Python and Perl scripting and is learning the ropes on AWS cloud, DevOps tools, and methodologies. He enjoys sharing the knowledge he's gained over the years with the rest of the community.