Linux namespaces are the underlying technology behind container technologies such as Docker. They are a feature of the Linux kernel that allows the system to limit the resources that container processes see, and that ensures that none of them can interfere with another.
What are namespaces?
When running many different processes and applications on a single server, as is the case with distribution tools such as Kubernetes, it is important that each process is isolated, mostly for security.
A container should not be able to gain control over others̵7; resources, because if that container is compromised, it can jeopardize the entire system. This attack method is similar to how CPU bug Meltdown works; different wires in a processor should be isolated from each other. Similarly, processes running on different virtual systems (containers) should be isolated from other containers.
Namespaces achieve this isolation at the core level. In the same way that the chroot application works, which captures a process in another root directory, namespaces separate other aspects of the system. There are seven namespaces available:
- Mount, or
mnt. Very similar
chroot, Mount namespace practically partitions the file system. Processes running in separate mount namespaces cannot access files outside their mount point. Because this is done at the core level, it is much safer than changing the root directory with
- Process, or
pid. In Linux, the first processes play as children of PID 1, which is the root of the process tree. The process name area cuts off a branch of the PID tree and does not allow access further up the branch. Processes in child namespaces will actually have multiple PIDs – the first one representing the global PID used by the master system and the second PID representing the PID in the child process tree, which is restarted from 1.
- Interprocess communication, or
ipc. This namespace controls whether processes can talk directly to each other or not.
- Network, or
net. This namespace handles which network devices a process can see. However, this does not automatically set anything up for you – you still need to create virtual network devices and manage the connection between global network interfaces and child network interfaces. Containerization software like Docker has already come up with this and can manage networks for you.
- User. This namespace allows the process to have “virtual root” in its own namespace without actually having root access to the parent system. It also separates UID and GID information, so that the child namespace can have its own user configurations.
- UTS. This namespace controls hostnames and domain information and allows processes to believe that they are running on different named servers.
- Cgroup is another core function that is very similar to namespaces. Cgroups allow the system to define resource boundaries (CPU, memory, disk space, network traffic, etc.) for a group of processes. This is a useful feature for container apps, but it does not do any kind of “information isolation” as the namespace would do. The cgroup namespace is a separate thing and only controls which cgroups a process can see, and does not assign it to a specific cgroup.
By default, all processes you run use global namespaces, and most processes in your system do so unless otherwise noted.
Work with namespaces
You can use
lsns command (ls-namespaces) to display the current namespaces that your system has active. This command must be run as root, otherwise the list may be incomplete.
lsns output from a new Ubuntu installation. Each namespace is listed next to the process ID, user, and command that created it. The seven namespaces were created from
/sbin/init with PID 1 are the seven global namespaces. The only other namespaces are
mnt namespaces for system daemons, along with Canonicals Livepatch service.
If you worked with containers, the list would be much longer. You can output this list in JSON format with
-J flag, which you can use much more easily with a scripting language.
You can change your current namespace with
nsenter tool. This command allows you to “specify” the namespace of another process, usually for debugging purposes. It can actually run any command in that namespace, but by default it only tries to load one shell (
You enter a process ID and then each namespace you want to enter:
sudo nsenter -t PID --mount --net --pid //etc.
For example, try specifying the mount name range for
kdevtmpfs will load you in that namespace, but then fails because it can not be found
/bin/bash, which actually means that it worked, because the obvious root directory was changed.
About your child
mnt namespace included
/bin/bash, you can enter it and load a shell. This can be done manually but should be done through binding brackets, which can manipulate the directory tree and link files anywhere
mnt namespace. This can lead to some interesting use cases, such as having two processes read different content from the same file.
To create new namespaces, you must fork from an existing one (usually globally) and specify which namespaces you want to change. This is done with
unshare command, which executes a command with a new namespace “shared” from the master.
To disable hostname names, use:
sudo unshare -u command
If the command is left blank,
unshare run bash by default. This creates a new namespace that will be displayed in
The terminal multiplexer
screen is used here to keep the bash running in the background, otherwise the namespace would disappear when the process was closed.
Unless you are doing programming at a very low level, you probably do not need to touch the namespaces yourself. Container programs like Docker handle the details for you, and in most cases where you need process isolation, you should only use an existing tool. However, it is important to understand how the namespace works in connection with containerization, especially if you are doing a low configuration of your Docker containers or need to do some manual troubleshooting.