How do Linux namespaces isolate containers, and what can't they protect against?
Quick Answer
Namespaces split kernel resources so each container has its own isolated view of PIDs, network, mounts, and user IDs. However, namespaces alone cannot limit resource usage, filter system calls, or stop kernel-level exploits since all containers share the same kernel.
Detailed Answer
Think of a large office building where each company has its own reception desk, phone system, and mailroom. From inside their suite, each tenant thinks they have the whole building. But the structure itself, the walls, plumbing, and electrical systems, is shared. Linux namespaces create these virtual suites: each container gets its own view of system resources, but the kernel (the building's infrastructure) is shared and needs other protections.
Namespaces are the foundation that makes containers possible. Before namespaces, every process on a Linux system shared the same PID space, network stack, mount tree, and user database. Namespaces split these global resources into separate instances. When a container runtime like runc creates a container, it calls clone() or unshare() with flags like CLONE_NEWPID, CLONE_NEWNET, CLONE_NEWNS, and CLONE_NEWUSER. Each flag creates a new isolated instance of that resource type for the child process.
PID namespace gives a container its own process numbering starting from PID 1, so the container's main process cannot see or send signals to host processes. Network namespace creates a separate network stack with its own interfaces, routing tables, firewall rules, and port space; virtual ethernet pairs (veth) bridge the container's network to the host. Mount namespace gives the container its own filesystem view: it sees its root filesystem from the container image and any explicitly mounted volumes, but not the host's filesystem or other containers' files. User namespace maps UIDs inside the container to different UIDs on the host, so UID 0 (root) inside the container can actually be UID 100000 on the host, preventing privilege escalation if a process escapes the container.
At production scale on hosts running 50-100 containers, namespace isolation must be paired with cgroups for resource limits, seccomp for system call filtering, AppArmor or SELinux for mandatory access control, and read-only root filesystems. Monitoring should track namespace counts per host (visible in /proc/sys/user/max_*_namespaces), network namespace interface counts, mount point buildup after container restarts, and user namespace mapping configurations. Kubernetes uses all four major namespace types, and understanding them is key for debugging container networking issues, PID-based health checks, and volume mount permissions.
The non-obvious catch is that namespaces do not protect against kernel-level attacks. Every container shares the host kernel, so a kernel vulnerability (like a privilege escalation bug in a system call handler) can break through all namespace boundaries. User namespaces help prevent simple UID 0 escalation but cannot stop kernel exploits. Some resources are not namespaced at all: kernel modules, most /proc/sys tunable settings, and the system clock (until time namespaces arrived in kernel 5.6) are shared across all containers. A container that loads a kernel module or changes a shared sysctl setting affects every other container on the host.