On this page
Hi everyone 👋, I'm Hung Anh.
This is the fourth article in the Kubernetes Fundamentals series. In the previous article, we ended on a question: if most VMs on a server only need to share the same OS, does each one really need to carry around its own complete kernel? Let's see how the container answers that.
Let's get started.
1. What Is a Container?
A container is an ordinary process on the host — nothing more exotic than that. What makes it look like it's running in its own separate machine is that the kernel "locks it in" using isolation mechanisms it already ships with: namespaces and cgroups, exactly the two we built by hand back in the first article of this series.
Unlike a VM, a container has no kernel of its own. It doesn't go through a hypervisor at all — it runs directly on the host's real kernel, just isolated from everything else also running there.
2. How a Container Works
When a container starts, the system does something remarkably plain: it creates a new process on the host — fast, the same as starting any other program — then applies two kernel mechanisms to that process:
- Namespaces — the container can't see the processes, files, or network of the host or of any other container.
- cgroups — the container is capped on how much CPU, RAM, and disk I/O it's allowed to consume.
That process makes syscalls straight to the host's real kernel — no emulation layer in between. That's the core difference from a VM, and exactly why a container is lighter and starts so much faster.
3. How This Solves the Previous Article's Problem
Because a container skips the hypervisor and the guest OS entirely, it avoids everything that made a VM heavy: no full OS to boot (starting a container is just starting a process — under a second, not minutes), no GBs spent just keeping a guest kernel alive, and far more containers can fit on the same hardware than VMs ever could.
4. The Downsides of a Container
- Weaker isolation than a VM. Since every container on the host shares the same kernel, a vulnerability in that kernel can potentially affect every container running on it — unlike a VM, where each one has a fully separate kernel.
- Tied to the host's kernel. A Linux container needs a Linux kernel underneath it to run at all. Want to run a Windows container? You need a Windows kernel/host to match.
How does Docker Desktop run Linux containers on Windows, then? The overwhelming majority of container images out there (nginx, postgres, node...) are Linux containers, and the Windows kernel simply doesn't understand them. So when you install Docker Desktop on Windows, it quietly runs a lightweight Linux VM in the background via WSL2 — the exact model from the previous article — and every "Linux container" you run is actually running inside that hidden VM, not directly on the Windows kernel. Docker just makes it feel native.
5. Container Runtime
Namespaces and cgroups are just mechanisms the kernel provides — something still has to actually call them to create, start, stop, and delete a container. That's the job of the container runtime.
Kubernetes doesn't want to be locked into one specific runtime, so it defines a standard interface first — the Container Runtime Interface (CRI) — and lets different runtimes implement it:
- containerd — split out of Docker, the most widely used default runtime in Kubernetes today.
- CRI-O — built from scratch specifically to follow the CRI standard.
Because kubelet (the Kubernetes agent covered in the next article) only ever talks to the CRI standard, swapping the runtime underneath never requires changing kubelet itself.
6. Summary
A container is just a regular process, isolated with namespaces and cgroups, running directly on the host's own kernel — no hypervisor, no guest OS. That's what makes it light and fast, at the cost of weaker isolation and a hard dependency on the host's kernel. A container runtime is the piece of software that actually creates and manages them.
Time to relax for a bit — next up: with containers now scattered across dozens or hundreds of machines, who decides which one runs where? That's exactly the problem Kubernetes exists to solve.
Happy reading! 🍵
References
- What even is a container: namespaces and cgroups - Julia Evans
- Container Runtime Interface (CRI) - Kubernetes documentation
Related articles
Kubernetes: Architecture and Components
With containers now scattered across dozens or hundreds of machines, who decides which one runs where, restarts it when it dies, or scales it up under load? That's the exact job Kubernetes was built for — let's map out what's actually inside a cluster.
Basic Linux Terminology
Before getting anywhere near Kubernetes itself, the story has to start with the one piece of software everything else in this series is built on top of: the Linux kernel. If you've never really sat down and thought about what a kernel does, what a driver is, or what "sandbox" actually means in Linux, this article is for you.
Physical Servers and Their Limits
What does a physical server actually look like, and why can't we just keep deploying more onto the same one?