In this article we will explain what Linux namespaces are and how do we take advantage of them in our software systems nowadays.
Let’s start!
What Is a Namespace?
A Linux namespace is a feature that Linux kernel provides to allow us to isolate resources for a set of processes. In some way, they are a sort of implementation of the bulkhead pattern we frequently see in microservices architectures.
What are the main advantages in the use of namespaces? The main advantages are two:
- Isolation of resources
One troublesome process won’t be taking down the whole host, it’ll only affect those processes belonging to a particular namespace. - Security
The other advantage is that a security flaw in the process or processes running under a given namespace, won’t give access to the attacker to the whole system. Whatever he/she could do, will always be contained within the boundaries of that namespace! This is why it’s also very important to avoid running our processes using privileged users whenever possible.

Namespaces and Containers
Nowadays, containers make extensive use of Linux namespaces to be able to group processes and provide resource isolation for them. Some of the most popular and user-friendly container engines at the moment are Docker or Podman.
Namespaces (and therefore containers) are something unique to the Linux kernel. You might be wondering, how is possible that we can run Docker or Podman in our Mac (OSX) or Windows machines then?
Well, the answer is simple: Both Docker and Podman run a virtual machine in your local machine (OSx or Windows) to be able to make use of namespaces and any other kernel features required to run containers.
For example, we are running Podman in our local machine, in order to make it work we had to initialise and start a podman machine first by running the following:
$ podman machine init
$ podman machine start
This initialises and starts a virtual machine in your local machine, which runs a linux operating system. How can we get the details about this machine to make sure that it’s actually a virtual machine? We can get this information by running this command:
podman machine inspect
This will inspect the default machine we have currently running in podman. The output will be something similar to this:
[
{
"ConfigPath": {
"Path": "/Users/theboreddev/.config/containers/podman/machine/qemu/podman-machine-default.json"
},
"ConnectionInfo": {
"PodmanSocket": {
"Path": "/Users/theboreddev/.local/share/containers/podman/machine/podman-machine-default/podman.sock"
}
},
"Created": "2023-02-12T07:50:02.100074Z",
"Image": {
"IgnitionFilePath": {
"Path": "/Users/theboreddev/.config/containers/podman/machine/qemu/podman-machine-default.ign"
},
"ImageStream": "testing",
"ImagePath": {
"Path": "/Users/theboreddev/.local/share/containers/podman/machine/qemu/podman-machine-default_fedora-coreos-37.20230205.2.0-qemu.aarch64.qcow2"
}
},
"LastUp": "2023-02-12T07:50:02.100074Z",
"Name": "podman-machine-default",
"Resources": {
"CPUs": 1,
"DiskSize": 100,
"Memory": 2048
},
"SSHConfig": {
"IdentityPath": "/Users/theboreddev/.ssh/podman-machine-default",
"Port": 56324,
"RemoteUsername": "xxxx"
},
"State": "running"
}
]
You can see above how Podman uses QEMU to run a virtual machine, using an image which runs Fedora Core OS as the operating system. If you want to run a different Linux version, our article “Run Ubuntu on Max Using QEMU” might be useful.

The way it works in Docker is very similar to what Podman does, although Docker uses VirtualBox instead. This is the default virtual machine that comes with Docker Desktop, but there are other alternatives like colima for example.
Now that we know what a Linux namespace is, you could be thinking: How can I create a new namespace?
Let’s see how!
How to Use Namespaces
In order to create a namespace in Linux, we have to use the unshare
command to run a process in a new namespace.
If we consult unshare
command’s help section, the first we can see is something like this:
$ unshare --help
Usage:
unshare [options] [<program> [<argument>...]]
Run a program with some namespaces unshared from the parent.
Options:
-m, --mount[=<file>] unshare mounts namespace
-u, --uts[=<file>] unshare UTS namespace (hostname etc)
-i, --ipc[=<file>] unshare System V IPC namespace
-n, --net[=<file>] unshare network namespace
-p, --pid[=<file>] unshare pid namespace
-U, --user[=<file>] unshare user namespace
-C, --cgroup[=<file>] unshare cgroup namespace
-T, --time[=<file>] unshare time namespace
You can see how most of the first few options allow us to specify different types of namespaces, these are the different types of namespaces we have in Linux systems. We will see cgroups
in more detail in a future article, as it takes a very important role in the containers world.
Types of Namespaces
Each type of namespace is different and it provides isolation for different resources in our system.
If we check the namespaces in the Linux manual pages, we can see a list of namespace types:
Namespace Flag Page Isolates
Cgroup CLONE_NEWCGROUP cgroup_namespaces(7) Cgroup root
directory
IPC CLONE_NEWIPC ipc_namespaces(7) System V IPC,
POSIX message
queues
Network CLONE_NEWNET network_namespaces(7) Network
devices,
stacks, ports,
etc.
Mount CLONE_NEWNS mount_namespaces(7) Mount points
PID CLONE_NEWPID pid_namespaces(7) Process IDs
Time CLONE_NEWTIME time_namespaces(7) Boot and
monotonic
clocks
User CLONE_NEWUSER user_namespaces(7) User and group
IDs
UTS CLONE_NEWUTS uts_namespaces(7) Hostname and
NIS domain
name
We won’t get into too much detail, but you can clearly see how every namespace will isolate a different resource in our system. Therefore, we can see briefly what the different types of namespaces in a Linux system are:
- User namespace
Contains an independent set of user IDs and group IDs that can be assigned to processes. - PID namespace
Contains its own set of process IDs (PIDs). Every time we create a new namespace, the process will get assigned PID 1. Every child process created in the new namespace will be assigned subsequent IDs. - Mount namespace
They allow the management of mount points in our system. Doing unmount in our new namespace won’t have any effect on the main host, as every new mount will be private to the current namespace. - Network namespace
Virtualises the network stack for the new namespace. This means that the new namespace will have its own virtual interface/s, private IPs, IP route table, sockets, etc. - IPC (Inter-Process Communication) namespace
Allows defining shared memory segments between processes within a namespace for inter-process communications, not interfering with other namespaces. - UTS (Unix Time-Sharing) namespace
Allows our system to have different host names and domain names for each namespace. - Time namespace
This namespace was released quite recently in Linux (2020), it allows having different system times within our system by specifying different time namespaces. - CGroup (Control Groups) namespace
Introduced in 2016 as part of Linux release 4.6, limits the resource usage in our system (cpu, memory, disk, etc) for a particular group of processes (under this namespace). As we will see in future articles, this is a very important feature of Linux Kernel in the containerised world we now live in!
Now that we have gone through all the existing types of namespaces in Linux, we’re going to show a simple example to understand the power that namespaces bring to us.
Let’s run the following command:
$ unshare --user --pid --map-root-user --mount-proc --fork bash
What exactly are we doing here? What are we telling the Kernel to do? Let’s go step by step to try to understand what we are doing.
If we check each of these options in the manual here, we can see each of these options tell the Kernel to do the following:
- –user: Create a new user namespace.
- –pid: Create a new pid namespace. (Will fail if –fork is not specified)
- –map-root-user: Wait to start the process until the current user (running
unshare
command) gets mapped to the superuser in the new namespace. This allows having root privileges within the namespace, but not outside of that scope. - –mount-proc: Mount
/proc
filesystem in the new namespace and create a new mount, this is to be able to have different processes with same process IDs in both namespaces. - –fork: Run command as a child process of the
unshare
command, instead of running it directly. It’s required when creating a new PID namespace.
Let’s see what this implies. First of all, if we list the processes in the new namespace, we only see the new processes running in the new namespace and not the processes running in the host’s default namespace:
$ ps -ef
PID USER TIME COMMAND
1 root 0:00 /bin/bash
2 root 0:00 ps -ef
This is because we’ve used both --pid
and --fork
options.
You will also notice that our processes are running as root
within the new namespace, this is what the --map--root-user
does. The current user is root
within this namespace only, this user won’t be able to do any harm to any of the external namespaces! This is great, right?
Lastly, we can see how the IDs of the processes are 1 and 2, this is because we create a new /proc
mount for our namespace using --mount-proc
.
Is that clear? We hope so!
It’s also worth mentioning that the unshare
command we just ran is equivalent to the following command using a docker/podman client:
docker exec -it myImage /bin/bash
This will be very familiar to those used to work with containers, as this is normally used to gain access through a terminal inside the container. Now that we’ve mentioned containers, let’s see what the namespaces role is inside of Linux containers.
Namespaces Role in Containers
Namespaces have been available in the Linux kernel since 2002, however, the use of them was restricted to those with a very advanced knowledge of Linux systems. Linux namespaces and containers were made “popular” by Docker, when it made possible a wide adoption of containers across the sector for anyone with a minimum (or zero) understanding of Linux Kernel internals.
The use of namespaces is not transparent to the users, and that’s probably why most users don’t understand containers in they way they actually are.
There’s a considerable number of people in the sector that see containers as some sort of virtual machine that does not contain the kernel, but shares it with the host instead. This is a wrong understanding of what a container is, we’ll see why very soon.

Containers create an illusion that could make you think that you’re actually running a virtual machine on your host, but this is far from the truth. When you run a virtual machine on your host , you are actually booting a new OS distribution on your machine, with the difference being that this OS will make calls to a middleware provided by the virtualisation engine you use (Virtual Box, QEMU, etc).
This middleware translates every kernel call inside your virtual machine to a system call that your host can understand. This is what mades possible, for example, to run different operating systems like Windows on a unix system!

On the other hand, a Linux container makes use of Linux namespaces to provide this illusion of running a different operating system. When we create an image based a any known Linux distribution, we are actually mounting its filesystem, giving us the impression of being on a new operating system. But actually we’re just inside of a new namespace!

Image Credit: Author
If you are interested in knowing more about Linux or UNIX systems, we recommend the following books:
Conclusion
In this article we have seen what Linux namespaces are and the very important role they play in distributed systems nowadays. We’ve also tried to clarify one of the biggest misconceptions around Linux containers with regards to Linux namespaces and virtual machines.
We really hope that every concept is now clearer to you. If you are still confused and this is unclear, don’t worry, this can happen. Just re-read these concepts and eventually you will get the point of Linux namespaces.
That’s all from us today! We really hope you’ve enjoyed reading this article as much as we enjoyed writing it!
Please follow us to be notified about new content like this one! Thanks for reading us!
You must log in to post a comment.