4.2.41 · D5Operating Systems

Question bank — Containers — namespaces, cgroups, difference from VMs

1,398 words6 min readBack to topic

Two words carry this whole page, so pin them first:

  • namespaces = what a process can SEE (isolation of view).
  • cgroups = what a process can USE (limits on resources).

If a trap confuses you, ask: is this about seeing (namespaces) or using (cgroups) — or about how many kernels exist (container vs VM)?


True or false — justify

A container runs its own operating-system kernel.
False. A container is a host process; it shares the host kernel via clone flags. Only a VM boots its own guest kernel.
uname -r inside a container shows a different kernel version from the host.
False. There is exactly one kernel, so the version string is identical. A different result would prove you are in a VM, not a container.
You can run a Windows container on a Linux host with no VM.
False. Windows binaries make Windows syscalls the Linux kernel doesn't implement; "Docker for Windows" secretly runs a lightweight Linux VM to host Linux containers.
cgroups provide isolation between containers.
False. cgroups cap quantity (RAM, CPU), not visibility. Without namespaces a process can still see and kill host processes — isolation comes from namespaces.
Two containers with memory.max = 512M each are guaranteed 512 MB.
False. memory.max is a ceiling, not a reservation. It stops a group from exceeding 512 MB but promises nothing about availability if the host is short on RAM.
Deleting a mount namespace's mounts affects the host's mount table.
False. A mount namespace gives a private copy of the mount table; changes inside stay inside unless the mount is explicitly shared.
A container is inherently more secure than a VM.
False. Sharing one kernel means a kernel bug is a shared blast radius; a VM's hardware-enforced boundary is generally stronger, just heavier.
Namespaces alone are enough to build a usable container.
False. Namespaces hide neighbours but don't stop a fork-bomb or memory hog; you also need cgroups to cap usage. You need both.
chroot gives the same isolation as a mount namespace.
False. chroot only changes the apparent root directory and is escapable; a mount namespace isolates the entire mount table and is a real kernel boundary.

Spot the error

"A container boots an OS, just a stripped-down one."
The error is "boots an OS." A container starts a process on the already-running host kernel — no boot, no init of a second kernel. The "OS" you see is just files (an image) plus namespaces.
"Root inside the container is root on the host, always."
With a user namespace, container UID 0 is mapped to an unprivileged host UID (e.g. 100000). Rootless containers rely on exactly this so container-root can't touch protected host files.
"Namespaces are created by a special container daemon."
They are created by kernel syscallsclone with CLONE_NEW*, unshare, setns. A daemon like Docker merely calls them; it invents no isolation of its own.
"docker exec starts a new container to run your command."
It joins the existing container's namespaces with setns(fd, type), then runs your command there. No new container, no new namespaces — it steps into the ones already open.
"cgroup v2 lets each controller live in its own separate hierarchy."
That describes cgroup v1. cgroup v2 is a unified hierarchy: one tree, controllers enabled per-node. The v1 multi-hierarchy design was the thing v2 replaced.
"A container's IP address is the host's IP address."
With its own network namespace a container has a separate network stack — its own interfaces, IPs, and ports — usually joined to the host via a virtual pair and bridge, not sharing the host IP.
"Setting cpu.max to a big number gives the container priority over others."
cpu.max sets an upper limit (quota/period), not a priority. Relative priority comes from CPU shares/weight under the CFS scheduler — a different knob.

Why questions

Why can a container start in milliseconds while a VM takes seconds?
A container only forks a process and swaps its namespaces/cgroups; a VM must emulate hardware and boot an entire guest kernel + OS first.
Why does the first process in a new PID namespace become PID 1?
A fresh PID namespace starts its own numbering from 1, so the host's hundreds of PIDs are invisible in this private table — the first process to enter it takes the number 1.
Why do we OR together several CLONE_NEW* flags instead of one master "isolate" flag?
Each flag privatises exactly one global table (PIDs, mounts, net…). ORing lets you choose which resources to isolate — e.g. share the network but not the filesystem — giving fine-grained control.
Why is a shared kernel called a "shared blast radius"?
All containers execute on the same kernel code, so one kernel vulnerability or panic can compromise or crash every container at once — unlike VMs, each with an independent kernel.
Why does writing a PID into cgroup.procs immediately start enforcing limits?
That write moves the process into the group; from then on the same host kernel accounts its usage against the group's controllers and enforces caps (e.g. OOM-kill past memory.max).
Why do rootless containers exist if root-in-container already feels isolated?
Because without a user namespace, a container escape could act as real host root. Mapping container-root to an unprivileged host UID shrinks the damage an escape can do.

Edge cases

A process is put in a cgroup but shares all namespaces with the host — is it a container?
No. It's a normal process with a resource cap: it can still see and kill host processes. A container needs namespaces for isolation, not just a cgroup.
A process gets every CLONE_NEW* namespace but no cgroup limits — is it isolated?
View-isolated, yes; usage-limited, no. It sees nothing shared, but nothing stops it from consuming all RAM/CPU or fork-bombing the host.
memory.max is set below the process's current usage — what happens?
The kernel tries to reclaim pages; if it can't get under the new limit, it OOM-kills a process in the group. The limit is enforced continuously, not just at fork time.
cpu.max uses its full quota mid-period — what does the process do?
It is frozen (throttled) until the next period refills the quota, then resumes. Over time it averages exactly quota/period of one core.
pids.max = 100 and a fork-bomb hits it — what stops?
New fork/clone calls in the group fail once 100 tasks exist, halting the bomb inside the group without touching the host's other processes.
A container with no network namespace — what's its network view?
It shares the host's network stack directly: same interfaces, IPs, and ports. Isolation of networking only appears when a net namespace is created.

Recall One rule that resolves most traps

"See vs Use, Curtains vs Chores; one kernel = container, many kernels = VM." Namespaces ::: curtains — control what you SEE. cgroups ::: chores — cap what you USE. Container ::: a curtained room in the existing house (one kernel). VM ::: a whole new house next door (its own kernel).