Living in a Private Universe
Cgroups answer the question: how much can a process use? Namespaces answer a different question: what can a process see?
A namespace is a kernel feature that wraps a global system resource in an abstraction layer, making it appear to processes inside the namespace as if they have their own private instance of that resource. Processes outside the namespace cannot see or interact with what is inside it.
The analogy: imagine a hotel. The hotel has one building (one kernel, one set of hardware). Each room is a namespace — guests in room 301 cannot see into room 302, cannot use room 302's phone, and believe they have their own private bathroom. The hotel staff (the kernel) knows about all rooms simultaneously, but enforces the walls between them.
The seven Linux namespaces:
| Namespace | Flag | What It Isolates |
|---|---|---|
| PID | CLONE_NEWPID |
Process ID number space |
| NET | CLONE_NEWNET |
Network interfaces, IP addresses, routing tables, firewall rules |
| MNT | CLONE_NEWNS |
Filesystem mount points |
| UTS | CLONE_NEWUTS |
Hostname and domain name |
| IPC | CLONE_NEWIPC |
System V IPC, POSIX message queues |
| USER | CLONE_NEWUSER |
User and group ID mappings |
| CGROUP | CLONE_NEWCGROUP |
Cgroup root directory visibility |
The three most important namespaces in practice:
PID Namespace: Inside a PID namespace, the first process gets PID 1. It cannot see any processes outside its namespace. This is why ps aux inside a Docker container shows only the container's processes, not the thousands of processes on the host. The host kernel still assigns a real PID to every process (e.g., 18432), but the process itself sees only its namespace-local PID (e.g., 1) — two views of the same process, mediated entirely by which PID namespace you're looking from.
NET Namespace: Each network namespace gets its own loopback interface, its own eth0 (or veth pair), its own IP address, and its own iptables rules. This is why two containers can both listen on port 8080 simultaneously without conflict — they are in different network namespaces, so their port 8080 is not the same port 8080.
MNT Namespace: Each mount namespace has its own view of the filesystem tree. A container's MNT namespace is initialized with a different root filesystem (the container image), so the container sees /etc/passwd from its image, not from the host. The host's /etc/passwd is completely invisible to the container.
How namespaces and cgroups combine to make a container:
Container = Namespaces (isolation) + Cgroups (limits)
Namespaces answer: "What can this process see?"
- Its own PID 1, not host PIDs
- Its own network interface, not host network
- Its own filesystem root, not host filesystem
Cgroups answer: "How much can this process use?"
- Max 512 MB RAM
- Max 50% of one CPU core
- Max 100 MB/s disk I/O
No new kernel features were invented to create Docker. Docker is an orchestration layer that calls clone() with the right namespace flags and writes to the cgroup filesystem. Understanding this means you can reason about container security, performance, and failure modes from first principles.