Namespaces: The Walls
In one sentence: A namespace is a kernel feature that gives a process a private, restricted view of one global resource — and a container is just a process wrapped in six of them.
You already know
- From Lesson 2: containers share the host kernel, which lies to each process tree about what exists.
- From Lesson 3: the OCI runtime asks the kernel to "create namespaces" before exec'ing the app.
One wall per resource
The kernel doesn't have a single "isolate this process" switch. Instead it offers one namespace type per global resource, and the runtime opts into each. The six that matter: PID (process gets its own process tree, sees itself as PID 1), MNT (its own mount table, hence its own filesystem root), NET (its own network interfaces, IPs, ports), UTS (its own hostname), IPC (its own shared-memory world), and USER (its own user IDs — root inside can be nobody outside). Because they're independent, you can mix walls: two containers can share a NET namespace while keeping separate PID trees — that's exactly how Kubernetes pods work.
flowchart LR P["container process
(sees itself as PID 1)"] PID["PID ns
private process tree"] MNT["MNT ns
private mount table / rootfs"] NET["NET ns
private interfaces + ports"] UTS["UTS ns
private hostname"] IPC["IPC ns
private shared memory"] USR["USER ns
private UID mapping"] P --- PID P --- MNT P --- NET P --- UTS P --- IPC P --- USR
Walls go up before the app wakes
Ordering matters: every namespace is created and furnished before the application process replaces the runtime's child via exec. From the app's first instruction, the lie is already complete — it has never seen the real host.
sequenceDiagram participant R as OCI runtime participant K as Kernel participant A as App process R->>K: clone child with new PID, MNT, NET, UTS, IPC, USER ns K-->>R: child exists inside fresh namespaces R->>K: furnish: mount rootfs, set hostname, map UIDs R->>A: exec the application note over A: first instruction runs —
the app has only ever seen the fake world
Anchor these
- One namespace type per global resource; a container opts into six.
- Namespaces are independent — they can be shared selectively between containers.
- Walls are fully built before exec; the app never glimpses the host.
See what actually stuck.
Take the practice scenarios now.