How it works
The explanation, with examples you can run.
What a namespace hides
Each namespace type wraps one kind of global resource. Docker gives every container its own mount, PID, network, UTS (hostname) and IPC namespaces, and on cgroup v2 hosts its own cgroup namespace. User namespaces, which map root in the container to an unprivileged user outside, are only used if you enable rootless mode or userns-remap.
docker run --rm alpine:3.22 ps# PID USER TIME COMMAND# 1 root 0:00 ps docker run --rm alpine:3.22 hostname# e758c8d8a3db (the container ID, not your machine's name)The process really is PID 1 inside its namespace, while the host sees it under an ordinary, larger PID. The same trick gives the container its own eth0, its own routing table and its own view of mounted filesystems.
What a cgroup limits
Namespaces do nothing about resources. A process in its own namespaces can still eat all the memory on the host. Control groups fix that: the kernel tracks every page and CPU slice used by a group of processes and enforces limits.
docker run --rm --memory 64m --cpus 0.5 alpine:3.22 \ sh -c 'cat /sys/fs/cgroup/memory.max /sys/fs/cgroup/cpu.max'# 67108864# 50000 10000064m became a hard memory ceiling of 67,108,864 bytes; --cpus 0.5 became a quota of 50 ms of CPU time per 100 ms period. Go over the memory limit and the kernel's OOM killer ends a process; go over the CPU quota and the process is simply paused until the next period (throttled). Kubernetes resource limits use exactly the same cgroup files.
Versus a virtual machine
A VM emulates hardware, boots its own kernel and runs a full OS on top. That gives strong isolation and lets you run Windows next to Linux, at the cost of seconds to boot and hundreds of megabytes of overhead. A container shares the host kernel, starts in milliseconds and adds almost nothing, but:
- it can only run software for the host's kernel (Linux containers need a Linux kernel, which is why Docker Desktop runs a VM on macOS);
- the kernel is the security boundary, so a kernel bug or an over-privileged container affects everyone on the host.
Many platforms combine the two: containers for packaging and density, inside VMs (or micro-VMs such as Firecracker) for isolation between tenants.
Where Docker fits
docker run asks the Docker daemon (dockerd) to create a container. The daemon prepares the image, network and mounts, then hands off to containerd, which uses runc to create the namespaces and cgroups and start your process. runc implements the OCI runtime specification, an open standard, which is why images built with Docker run unchanged under containerd, CRI-O or Podman.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.