Linux namespaces are the fundamental building blocks that give containers their perceived isolation.

Let’s see them in action with a quick example. Imagine you have a process running as root inside a container. From the container’s perspective, it’s uid 0. But outside, in the host system, it’s just a regular user.

# On the host, run a simple shell in a new PID namespace
sudo unshare --pid --mount-proc --fork --pid sh

# Inside the new shell (which is like a container environment)
whoami
# Output: root

ps aux
# Output will show processes running as root within this isolated PID namespace

The problem namespaces solve is this: how do you give a process the illusion of being the sole owner of a system resource (like PIDs, network interfaces, or mount points) without actually giving it a separate kernel or a full virtual machine?

Namespaces achieve this by partitioning kernel resources such that a process and its descendants have an isolated view of these resources. When a process is created within a new namespace, it gets its own instance of that particular namespaced resource. For example, a new PID namespace means the process sees PID 1 as its init process, even though the host might have thousands of processes running.

Here’s a breakdown of the key namespaces and what they isolate:

  • PID (Process ID): Isolates the process ID tree. Processes inside a PID namespace have their own set of PIDs, starting from 1. This is crucial for container orchestration, as it allows containers to manage their own process lifecycle without interfering with or seeing host processes.
  • Network (Net): Provides an isolated network stack. Each network namespace has its own network interfaces, IP addresses, routing tables, and firewall rules. This is what allows containers to have their own IP addresses and ports without conflicting with the host or other containers.
  • Mount (Mnt): Isolates the filesystem mount points. Processes in a mount namespace can have their own view of the filesystem hierarchy. This is how containers can have their own root filesystem (/) and mount/unmount devices without affecting the host.
  • UTS (UNIX Time-sharing System): Isolates the hostname and domain name. This allows containers to have their own distinct hostnames.
  • IPC (Inter-Process Communication): Isolates System V IPC objects and POSIX message queues. This prevents processes in one IPC namespace from seeing or interfering with IPC mechanisms in another.
  • User (User): Isolates user and group IDs. A process can have root privileges (UID 0) inside a user namespace, but be mapped to a non-privileged user on the host. This is a critical security feature, as it allows containers to run as root internally without granting actual root privileges on the host.
  • Cgroup (Control Group): Isolates the cgroup hierarchy. While cgroups are primarily for resource limiting, the cgroup namespace provides an isolated view of the cgroup tree.

When you run a container using a tool like Docker or Podman, it’s essentially creating a set of these namespaces for the container’s processes. Each container gets its own PID, network, mount, UTS, IPC, and user namespaces.

The most surprising truth about namespaces is that they don’t provide security on their own; they provide isolation. The security comes from how these isolated environments are configured and how they interact with the host. A poorly configured namespace, especially a user namespace, can still expose vulnerabilities. For instance, if a user namespace isn’t properly configured to map the container’s root user to a non-privileged host user, a process escaping the container could gain elevated privileges on the host.

Consider the user namespace. Without it, a process running as root (UID 0) inside a container would also be root (UID 0) on the host, which is a massive security risk. With a user namespace, you can map UID 0 inside the container to, say, UID 1000 on the host. This means that even if a process inside the container thinks it’s root, it only has the privileges of UID 1000 on the host.

# Example of user namespace mapping (simplified, actual configuration is more complex)
# In /etc/subuid and /etc/subgid, you define ranges for user/group IDs
# Then use 'unshare --user --map-root-user' to enter a new user namespace
# where your current user is mapped to UID 0 inside.

The next logical step after understanding isolation is how to manage and restrict the resources available within these isolated environments, which leads to control groups (cgroups).

Want structured learning?

Take the full Cdk course →