C.W.K.
Stream
Lesson 03 of 07 · published

What Docker Actually Does — Namespaces, cgroups, OverlayFS

~18 min · foundations, kernel

Level 0Container Curious
0 XP0/36 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Docker is a wrapper. The kernel does the work.

It is tempting to think Docker invented containers. It did not. Linux namespaces shipped in 2002, cgroups in 2007, OverlayFS in 2014. Docker (2013) made these primitives usable — same way Git made Linus Torvalds's content-addressable storage usable.

The three pillars

1. Namespaces — what each process can see

Each container gets its own view of:

  • PID — its own process tree (PID 1 inside is your app)
  • NET — its own network stack (interfaces, routing, ports)
  • MNT — its own filesystem mounts
  • UTS — its own hostname
  • IPC — its own shared-memory and semaphores
  • USER — its own UID/GID mapping (rootless mode)

2. cgroups — how much a container can use

Control Groups enforce CPU shares, memory limits, block I/O bandwidth, and PIDs per cgroup. A runaway container hits the wall instead of starving the host.

3. Union filesystems (OverlayFS) — layered images

Images are stacks of read-only layers. Container runtime adds a thin writable layer on top. Same base layer? Stored once on disk, mounted into many containers. This is why pulling an image of "size 200MB" often only downloads 30MB — the rest you already have.

Code

See your process tree from inside vs outside·bash
# Start a container that just sits there
docker run -d --name demo nginx

# From inside: PID 1 is nginx
docker exec demo ps -ef
# UID    PID  PPID  C STIME TTY    TIME CMD
# root     1     0  0 11:00 ?  00:00:00 nginx: master process
# nginx    7     1  0 11:00 ?  00:00:00 nginx: worker process

# From the host: those same processes show up with different PIDs
ps -ef | grep nginx
# root  4127  4099  0 11:00 ?  nginx: master process
# Same process, different PID — that is the PID namespace at work.
Watch cgroup limits in action·bash
# Run a memory-greedy container with a 100MB cap
docker run --rm --memory=100m python:3.12-slim python -c \
  'a = bytearray(200*1024*1024)'

# Output:
# Killed   ← OOM killer triggered by the cgroup, not the host

# The host stays healthy. Other containers keep running.
# Without --memory, that allocation could have OOMed your laptop.

External links

Exercise

Run two containers from the same image. Use docker exec ... ps -ef inside each, then ps -ef | grep <process> on the host. Note the PIDs from both views. Explain — in 2 sentences — why PID 1 inside the container is not PID 1 on the host.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.