Part 1: What Are Linux Namespaces
On a normal Linux system, everything seems to live in one big shared space.
Every process can see the same list of running programs, share the same network interfaces, and access the same filesystem hierarchy. If you open two terminals and run ps aux, both will display an identical process list because, at the kernel level, there’s only one global view of what’s happening.
But imagine you could split this system into several small “worlds,” each with its own view of processes, network, and files. In one world, a process might think it’s the only program running on the machine. In another, the hostname might be entirely different. Yet all of these worlds still share the same underlying kernel.
That’s exactly what Linux namespaces make possible.
Namespaces provide isolation at the process level, letting you control what a process can see or interact with in the system. Instead of creating an entirely separate virtual machine, the kernel simply gives processes their own private views of certain resources, like their own network stack, their own list of running processes, or even their own filesystem mounts.
This idea of controlled isolation forms the backbone of modern container technologies. When you start a Docker container, for example, you’re not creating a new operating system. You’re launching one or more regular Linux processes, but each of them runs inside a collection of namespaces that hide parts of the system from view.
This series will break down Linux namespaces and show how each one isolates a specific part of the system.
Along the way, you’ll see how these namespaces come together to form the foundation of modern container technology.
Each part will focus on a different namespace type , explaining how it works, how to experiment with it using standard Linux tools, and how those same mechanisms are used by containers behind the scenes.
In this first article, we’ll start with the basics: understanding what namespaces are, why they exist, and how to view them on a running system.
The Idea of Isolation in Linux
Linux was designed as a multi-user operating system. This means many users can run programs at the same time, often competing for the same resources, CPU, memory, files, and devices. While permissions control who can access something, they don’t always control how much or how isolated that access should be.
For example, every process on a system can normally see all other processes:
$ ps auxIf one process crashes or consumes too much memory, it could affect the rest of the system. That’s where isolation comes in, limiting what each process can see or influence.
Before namespaces existed, administrators used tools like chroot to isolate filesystems or ulimit to restrict resources. These were helpful, but they only covered specific aspects of isolation. Namespaces took the idea much further by letting the kernel isolate different kinds of system resources, not just files.
You can think of namespaces as a set of invisible containers around system resources. Each container defines what a process can “see”, whether that’s a process list, a network interface, or even the system clock.
This approach differs from virtualization. Virtual machines emulate an entire hardware environment and run their own kernel, while namespaces isolate resources within the same kernel. As a result, namespaces are lightweight and efficient, making them ideal for building container-like environments.
Sysxplore is an indie, reader-supported publication.
I break down complex technical concepts in a straightforward way, making them easy to grasp. A lot of research goes into every piece to ensure the information you read is as accurate and practical as possible.
To support my work, consider becoming a free or paid subscriber and join the growing community of tech professionals.
The Building Blocks of Containers
If you’ve used Docker, Podman, or LXC, you’ve already worked with namespaces, even if you didn’t notice it.
When you start a container, Linux doesn’t create a new operating system. Instead, it uses namespaces to isolate specific system resources for the container’s processes.
Inside a namespace, processes operate as if they have their own environment: their own process tree, network stack, and hostname.
From the host’s perspective, though, these are still ordinary processes managed by the same kernel, only their view of the system is limited.
Here’s is how I like to visualize it:
The kernel is like a theater stage, and each namespace is a separate play happening on that same stage. Every actor thinks their story is the only one, but the stage crew (the kernel) manages them all behind the scenes.
This ability to isolate processes without spinning up full virtual machines is what makes containers so lightweight. Each container runs as a regular Linux process, but with boundaries that limit what it can access or observe. The combination of namespaces (for isolation) and control groups (for resource limits) forms the foundation of modern containerization.
We’ll focus on namespaces throughout this series, exploring how they isolate different parts of the system and how you can interact with them directly from the command line, no container engine required.
The Types of Namespaces
Now that you have the big picture, let’s look at what Linux can actually isolate.
As of today, the Linux kernel supports eight different namespaces, each responsible for separating a specific part of the system.
Each namespace type creates its own isolated “view” of a resource. Processes inside that namespace only see what belongs to it, not the global system. Together, they let the kernel build virtual environments that behave like independent systems, all while sharing the same underlying OS.
Let’s briefly walk through each one.
Mount (mnt)
The mount namespace is the oldest of all. It isolates the filesystem hierarchy, giving each process its own view of mounted filesystems.
Any time you use the mount or umount command, you’re effectively interacting with this namespace.
With mount namespaces, a process can have its own private filesystem layout. You can mount or unmount directories inside that environment without affecting what’s visible to the host.
Before mount namespaces existed, administrators used chroot to change a process’s apparent root directory, a trick that limited what it could access, but without true isolation.
Mount namespaces take that concept further by giving each process an entirely separate set of mount points, not just a different starting directory.
That’s why container environments rely on mount namespaces rather than chroot: they provide stronger, kernel-enforced filesystem isolation and greater flexibility in defining what each process can see.
PID (pid)
The PID namespace isolates process IDs.
Each namespace has its own numbering system for processes, starting at PID 1, which acts like its own init process.
Processes in one PID namespace can’t see or interact with those outside of it.
This is what gives containers their own independent process trees. It also allows commands like kill to send signals only within the same namespace.
Behind the scenes, PID namespaces are hierarchical the parent namespace can still see all the processes inside the child namespace, but not the other way around.
Network (net)
The network namespace provides isolation for everything related to networking, interfaces, routing tables, port numbers, ARP caches, and firewall rules.
Each network namespace gets its own virtual network stack, complete with its own IP addresses and devices.
You can think of this as giving each container its own miniature network environment.
Docker, for example, connects containers by creating virtual Ethernet pairs (veth) and bridges between namespaces.
That’s how multiple containers can each run web servers on port 80 or 443 without conflicting.
UTS (uts)
UTS stands for UNIX Time-Sharing, and this namespace controls system identifiers, the hostname and domain name.
It lets each isolated environment appear to be a different machine.
When you change the hostname inside a container, it only affects that container’s UTS namespace.
This small but powerful feature makes each container feel like its own system, even though they all share the same kernel.
IPC (ipc)
The IPC namespace (Inter-Process Communication) isolates communication channels such as System V message queues, semaphores, and shared memory segments.
This prevents processes in different namespaces from accidentally reading or modifying each other’s messages.
It’s a security-focused namespace that dates back to UNIX System V.
Each IPC namespace maintains its own identifiers and POSIX message queue filesystem, ensuring one container’s internal communications remain private.
User (user)
The user namespace isolates user and group ID numbers.
Inside a user namespace, a process can appear to run as root even though it’s mapped to a non-privileged user on the host.
This allows for powerful yet safe privilege separation, a cornerstone of container security.
User namespaces can also be nested, meaning an unprivileged user in one namespace can create another one and become “root” inside it.
While this brings flexibility, it also raises some security considerations if not properly controlled.
Cgroup (cgroup)
The cgroup namespace hides and isolates the control group hierarchy from processes.
Cgroups (control groups) are used by containers like Docker and LXC to limit, measure, and isolate resource usage, CPU, memory, I/O, and more.
Before this namespace existed, processes could see cgroup information from other containers, leading to potential information leakage.
Now, each namespace has its own virtual view of cgroups, so processes can only see and manage their own resource quotas.
Time (time)
The time namespace is one of the newest additions to Linux.
It isolates system clocks such as the boot time and monotonic clock, allowing each namespace to maintain its own time offsets.
This means a container can adjust its own clock without affecting the host, useful for testing, simulations, or restoring snapshot environments where time shouldn’t jump forward.
It’s also what allows containers to run their own time synchronization processes, like ntpd, independently.
Together, these eight namespaces form for what has become the backbone of Linux’s process isolation model.
Each can be used individually, but when combined, as in most container environments, they create lightweight, secure, and flexible virtual systems that behave like independent machines.
In the upcoming parts of this series, we’ll explore each of these namespaces in action: how to create them, how to peek inside, and how to connect them to real-world container behavior.
Namespaces in Action – A Quick Peek
Before diving deeper into each namespace, let’s see what namespaces already exist on your system.
Even without Docker or containers, your Linux system uses namespaces all the time. Every process is part of one or more namespaces.
You can view them using the lsns (short for list namespaces) command, which comes with the util-linux package:
$ lsnsEach row represents a namespace, identified by its unique NS number.
The TYPE column tells you which resource it isolates, while NPROCS shows how many processes are currently using that namespace.
The PID column points to the process that created it.
You can also inspect namespaces for a specific process by looking under /proc/[PID]/ns:
$ ls -l /proc/1921/nsEach symbolic link in that directory corresponds to one namespace type.
For example, /proc/1921/ns/net points to the network namespace used by the systemd process.
In the next parts of the series, we’ll use similar experiments to explore each namespace type in depth, from process isolation to network segmentation, filesystem views, and more.
Looking Ahead
What we’ve seen so far is that namespaces don’t create new machines, they reshape how processes see the system. Every container, sandbox, or lightweight virtual environment you’ll ever use relies on this core concept.
In the upcoming parts of this series, we’ll walk through each namespace one at a time.
You’ll learn what it isolates, how to create it manually, and what real-world scenarios it’s used in.
Here’s a quick preview of what’s coming:
PID Namespace – Discover how Linux builds isolated process trees and why every container has its own PID 1.
Network Namespace – Create isolated networks, connect them with virtual interfaces, and understand how Docker wires them together.
Mount Namespace – Explore how filesystem views can differ across isolated processes and more.
In the next part, we’ll begin with PID namespaces, where you’ll see how Linux creates separate process worlds, each with its own “init” process and process list, so stay tuned.
Thanks for reading!
If you enjoyed this content, don’t forget to leave a comment, like ❤️ and subscribe to get more posts like this every week.












Really very helpful content
I am glad i found you here. Learning the fundamentals and essentials.