What are Linux namespaces and how do they enable containers?

Answer

Linux namespaces partition kernel resources so that different groups of processes see different views of those resources. A process's namespace determines what parts of the system it can see. Namespaces + cgroups = containers (no hypervisor needed). Namespace types (7 types): (1) PID namespace: processes have a different set of PIDs. Processes in a container see themselves as PID 1 (their container init); (2) Network namespace: isolated network stack — own IP addresses, routing tables, network interfaces, firewall rules. Container gets its own eth0; (3) Mount namespace: isolated filesystem mount points. Container sees its own root filesystem; (4) UTS namespace: isolated hostname and domain name. Container has its own hostname; (5) IPC namespace: isolated inter-process communication — shared memory, semaphores; (6) User namespace: isolated user and group IDs. Container root (UID 0) maps to unprivileged user on host — rootless containers; (7) cgroup namespace (Linux 4.6+): isolated view of cgroup hierarchy. Creating namespaces: unshare(1) or unshare(2) syscall: sudo unshare --pid --fork --mount-proc bash # New PID namespace ps aux # Only sees processes in this namespace. clone() flags: CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER. Docker implementation: each container gets a new set of namespaces. Files in /proc/[pid]/ns/ show which namespaces a process belongs to. Container runtime (runc, containerd) calls clone() with all CLONE_NEW* flags, then exec()s the container process. This is literally all a "container" is at the Linux level — no magic, no VM.