A process that thinks it is alone
A container isn't a tiny virtual machine. It's an ordinary process the kernel lies to about what it can see, and limits in what it can use.
People say “a container is a lightweight virtual machine”. It’s a handy picture and it’s wrong in a way that will bite you. A virtual machine runs its own kernel on pretend hardware. A container runs on your kernel, the same one every other process on the machine uses. It’s just a process.
What makes it feel like a separate machine are two Linux kernel features, applied to that process:
- Namespaces change what the process can see. In its own PID namespace it’s process number 1 and can’t see anyone else’s processes. In its own mount namespace it sees a different root filesystem. In its own network namespace it has its own interfaces and ports. The manual page puts it this way: a namespace wraps a global resource so that processes inside it appear to have their own isolated instance of it.
- cgroups (control groups) limit what the process can use: how much memory, how much CPU time, how many processes. Go over a memory limit and the kernel’s out-of-memory killer ends the process.
| Namespace | Makes the process think it has its own… |
|---|---|
| PID | process list (and it is PID 1) |
| Mount | filesystem tree |
| Network | network interfaces, IP addresses, ports |
| UTS | hostname |
| IPC | shared memory and message queues |
| User | user and group IDs (root inside, nobody outside) |
| Cgroup | view of the cgroup hierarchy |
| Time | boot and monotonic clocks |
The image is the other half: a bundle of files (a whole minimal Linux userland plus your app) and some settings, like which command to run. A container is an image’s files, unpacked into a mount namespace, with one process started inside it.
You run `ps aux` on the host while a container is running nginx. What do you see?
A container's processes are host processes. The host sees them with their real PIDs. Only the process inside the container has the narrowed view: its PID namespace shows it as PID 1, with no neighbours.
Why the difference matters
Because every container shares the host’s kernel:
- A Linux container needs a Linux kernel. On a Mac or Windows laptop, Docker Desktop quietly runs a small Linux virtual machine and runs your containers inside it.
- A memory limit is enforced by that shared kernel. The out-of-memory kill you’ll meet in the Kubernetes track,
OOMKilled, exit code 137, is a cgroup doing exactly its job. - Isolation is good but not a VM boundary. A kernel bug is a bug for every container on the machine at once, which is why people running untrusted code add sandboxes or real VMs.
A container has a 64 MiB memory limit and its process tries to use 200 MiB. What enforces the limit?
Limits are cgroup settings that the kernel enforces on every allocation. When the group is out of memory and nothing can be reclaimed, the kernel's OOM killer kills a process in it. That's the 137 / OOMKilled you'll diagnose later.
Can a container built for Linux run directly on the Windows kernel?
Portability is between machines with a compatible kernel. That's the real promise: same image, any Linux host. Docker Desktop on Windows and macOS runs a Linux VM so the shared-kernel model still holds.
Everything above ran in your browser. Now do it on a real cluster withthe tilt platform. You need Docker, kind and Tilt, about 15 GB of free disk and 8 GB of spare RAM. Setup guide · Can my machine run it?
With Docker installed, see the narrowed view from inside and the plain process from outside:
docker run --rm -d --name panda alpine sleep 300
docker exec panda ps # inside: sleep is PID 1; the only other process is ps itself
docker exec panda hostname # its own hostname (UTS namespace)
docker top panda # outside: the same process, with its host PID
docker rm -f pandaSources
Missions and quizzes above earn their own XP. This marks the lesson done.