CoursesDocker in depthThe Docker engine

How isolation works: namespaces & cgroups

The kernel features under every container.

Intermediate14 min · lesson 8 of 30

A container is a normal Linux process dressed up by two kernel mechanisms working together. Namespaces control what the process can see; cgroups control what it can use. There is no “container” object in the kernel — runc just starts a process inside a fresh set of namespaces with cgroup limits applied, and that combination is the container. Internalize this and both isolation and, later, its failure modes become obvious.

The two halves of isolation
namespaces — what it can SEE
pid
own process tree, own PID 1
net
own interfaces + ports
mnt
own filesystem view
uts / ipc / user
hostname, IPC, UID mapping
cgroups — what it can USE
memory
hard cap, OOM on breach
cpu
capped share
pids
max process count
Namespaces give the illusion of a private machine; cgroups keep one container from starving the rest of the host.

Namespaces: the private view

Each namespace type isolates one resource. In its own PID namespace a container sees only its own processes, with its entrypoint as PID 1. Its network namespace gives it its own interfaces and port space; its mount namespace, its own filesystem view; the user namespace can even map container root to an unprivileged host UID. You can watch this from both sides — PID 1 inside, a distinct namespace outside.

terminal
$ docker run --rm alpine ps -ef # inside: it is PID 1 and sees nothing else
PID USER COMMAND
1 root ps -ef
$ sudo lsns -t pid | grep -i alpine # on the host: its own dedicated pid namespace

Scenario: deliberately sharing a namespace

Isolation is the default, but sometimes you share a namespace on purpose. --pid=host lets a debugging container see and signal host processes (handy for troubleshooting, dangerous in production). --network=container:web puts a second container in the first’s network namespace so they share localhost — the classic sidecar pattern, and exactly how a pause container works in Kubernetes. Each shared namespace is a deliberate hole in the wall.

terminal
# sidecar: the proxy shares the app’s network namespace and reaches it on localhost
$ docker run -d --name web nginx:1.27
$ docker run --rm --network=container:web nicolaka/netshoot curl -s localhost:80 | head -1
<!DOCTYPE html>
# debugging: see host processes from inside a container (powerful, not for prod)
$ docker run --rm --pid=host alpine ps -ef | head

cgroups: the resource ceiling

cgroups cap what a container may consume so one workload cannot take down the node. --memory sets a hard ceiling (exceed it and the kernel OOM-kills the process), --cpus limits CPU share, and --pids-limit caps the process count — a cheap defence against a fork bomb. Without limits, a single container can consume all of a host’s memory or CPU.

terminal
$ docker run -d --name app --memory 256m --cpus 1.5 --pids-limit 200 myapp:1.0
$ docker stats --no-stream app
NAME CPU % MEM USAGE / LIMIT PIDS
app 2.1% 88MiB / 256MiB 37

Scenario: the noisy neighbor and the mystery kill

One unlimited container degrades everything else on the box, or a container keeps dying and nobody knows why. The fix for the first is limits; the diagnosis for the second is in the container’s state — OOMKilled true means it breached its memory cap and the kernel killed it, so either the limit is too low or the app is leaking. That single field turns “it just keeps restarting” into a concrete answer.

terminal
$ docker inspect -f '{{.State.OOMKilled}} exit={{.State.ExitCode}}' app
true exit=137 # 137 = 128 + SIGKILL(9): the kernel OOM-killed it
# raise --memory, or fix the leak — the number is not lying
This is the entire boundary
Namespaces and cgroups, plus capabilities and seccomp, are the whole wall between a container and the host kernel they share. It holds for normal workloads but is thinner than a VM’s, and every shared namespace (--pid=host, --network=host) or removed limit widens it. The advanced course builds a container from these primitives by hand and then walks the escapes that abuse them.