Knowing the kernel primitives demystifies isolation, limits and many container bugs.
There is no "container" object in the Linux kernel. A container is an ordinary process set up with two families of kernel features.
Namespaces control what a process can see. Each kind gives the process its own view of one global resource:
pid: its own process tree; the app is PID 1 and can't see host processes.net: its own interfaces, IPs, routing table and ports (a veth pair connects it to the bridge).mnt: its own mount table, with the image's root filesystem as/.uts: its own hostname.ipc: its own shared memory and semaphores.user: maps UIDs inside to different UIDs outside (used by rootless mode and userns-remap).cgroupandtime: virtualized views of the cgroup tree and of some clocks.
Docker's flags map straight onto these: --network host and --pid host mean don't create that namespace, and --network container:x joins another container's namespace.
Control groups (cgroups) control what a process can use: memory, CPU time, I/O bandwidth and number of PIDs, with accounting for each. Modern hosts use cgroup v2, a single unified hierarchy under /sys/fs/cgroup. With the systemd cgroup driver, a container lives in a scope like system.slice/docker-<id>.scope, where files such as memory.max, cpu.max and pids.max hold the limits you set with --memory, --cpus and --pids-limit.
Since a container is just a process, the host sees it: ps on the host lists it with a host PID, and nsenter can enter its namespaces. Together with capabilities, seccomp and LSMs (AppArmor/SELinux), these features make up container isolation, all sharing one kernel.
Example
docker run -d --name web --memory 256m --cpus 0.5 nginx:1.27
PID=$(docker inspect -f '{{.State.Pid}}' web)
ps -o pid,user,cmd -p "$PID" # visible from the host
sudo ls -l /proc/$PID/ns # net -> net:[4026532301] ...
sudo lsns -p "$PID"
# Enter just its network namespace with host tools
sudo nsenter -t "$PID" -n ip addr
# Its cgroup v2 limits (systemd driver)
CG=$(awk -F: '{print $3}' /proc/$PID/cgroup)
cat /sys/fs/cgroup$CG/memory.max # 268435456
cat /sys/fs/cgroup$CG/cpu.max # 50000 100000Remember
- Namespaces limit what a process sees: pid, net, mnt, uts, ipc, user, cgroup, time
- cgroups limit and account what it uses: memory, CPU, I/O, PIDs
- --network host / container:x skip or share a namespace
- A container is a host process; nsenter and /proc reveal it
Watch out for
- Treating namespace isolation as a security boundary equal to a VM — all containers share one kernel.