Two technologies both promise to run "someone else's software, isolated, on my machine": the virtual machine and the container. From a distance they look interchangeable — both give you a fresh Linux you can install things into, both are spun up by clouds by the million. But they solve the problem at opposite ends of the stack, and the difference decides your startup time, your density, your overhead, and — most importantly — how strong your isolation really is.
You already know both halves of the answer. A container, from the
Line the layers up and the story tells itself. On the left, each VM is a tall tower: on top of the
hypervisor sits a complete guest operating system — its own kernel, its own drivers, its own
Count the kernels. Ten VMs on a host means eleven kernels running (one host — well, the hypervisor — plus ten guests). Ten containers means one kernel, shared. That single fact drives every number in the trade-off table below.
Because a container skips the guest kernel, it skips guest boot, guest memory, and the hypervisor's world-switch overhead. Because a VM keeps the guest kernel, it keeps a hard hardware-enforced boundary the guest cannot see past. Neither is "better"; they trade the same axis in opposite directions — overhead versus isolation, the theme that has run through this entire course.
| Dimension | Virtual machine | Container |
|---|---|---|
| Virtualizes | the hardware | the OS interface |
| Guest kernel | yes — a full one per VM | none — shares the host kernel |
| Startup | seconds (full OS boot) | milliseconds (just |
| Memory footprint | hundreds of MB (kernel + OS baseline) | megabytes (only the app) |
| Density per host | tens | hundreds to thousands |
| Runtime overhead | a few % (hardware-assisted) | near zero — native syscalls |
| Isolation boundary | strong — hardware-enforced, own kernel | weaker — shared kernel = larger attack surface |
| Kernel choice | any guest OS (even Windows on Linux) | host kernel only (Linux on Linux) |
Read the last two rows together. A VM's strength (a private guest kernel) is exactly the source of its cost (booting and carrying that kernel); a container's strength (sharing one kernel) is exactly the source of its weakness (one kernel bug can breach every container). The engineering question is never "which is better?" but "for this workload and this threat model, which side of the axis do I want?"
Make it concrete. Suppose a host has
Because clouds run your code next to a stranger's code, and "weaker isolation" stops
being an abstraction when the neighbour is hostile. Multi-tenant serverless (AWS Lambda, Fargate) needs
container-like millisecond starts and VM-grade isolation — seemingly a contradiction. The answer,
which the last lesson of this module explores, is the microVM: a radically stripped
hypervisor (Firecracker) that boots a minimal guest kernel in around
The single most common misconception, repeated in a thousand blog posts: "a container is just a lightweight virtual machine." It is not lightweight because it is a small VM — it is lightweight because it is not a VM at all. There is no guest kernel to be light or heavy; there is no virtual hardware; the hypervisor is absent. It is a process. Getting this wrong leads to real errors: people assume a container isolates them from a kernel exploit the way a VM does (it does not), assume they can run a Windows container on a Linux kernel (they cannot — the kernel is shared, so a "Windows container" needs a Windows host or a hidden VM), and assume container escape and VM escape are equally hard (they are not — the container shares the kernel it must escape through). Say it precisely: a container is an isolated process; a VM is an emulated computer.