Containers vs. Virtual Machines
In one sentence: A VM virtualizes hardware to boot a whole guest operating system; a container virtualizes the operating system to isolate just a process tree — which is why containers start in milliseconds, not minutes.
You already know
- From Lesson 1: a container is a running instance of an image, managed by a daemon.
- VMs from everyday use: they're heavy, boot slowly, and each carries a full OS.
Two places to draw the line
Isolation always means drawing a line and lying to whatever is above it. A hypervisor draws the line at the hardware: each guest gets fake CPUs, fake disks, fake network cards, and must boot its own kernel to drive them. A container engine draws the line at the kernel's system-call interface: every container shares the one real host kernel, but the kernel lies to each process tree about what it can see — its own process list, its own filesystem root, its own hostname. Nothing boots; a container "starting" is just a normal process starting inside a set of kernel-enforced lies.
flowchart TB
subgraph VM["Virtual machines"]
direction TB
A1["App A"] --> G1["Guest OS + kernel A"]
A2["App B"] --> G2["Guest OS + kernel B"]
G1 --> HV["Hypervisor ⟵ isolation line"]
G2 --> HV
HV --> HW1["Hardware"]
end
subgraph CT["Containers"]
direction TB
B1["App A + libs"] --> K["Shared host kernel ⟵ isolation line"]
B2["App B + libs"] --> K
ENG["Container engine"] -. configures .-> K
K --> HW2["Hardware"]
end
The cost of the difference
Because a VM must initialize virtual hardware and boot a kernel, startup is measured in seconds to minutes and each guest costs gigabytes of memory before the app runs. A container skips all of it — the kernel is already running. The trade: containers offer a weaker boundary (one shared kernel means one kernel bug can cross the line), which is why Part 1 ends with a security lesson and Lesson 39 hardens it further.
sequenceDiagram
participant HV as Hypervisor
participant G as Guest OS
participant E as Container engine
participant K as Host kernel
rect rgb(253, 244, 235)
note over HV,G: VM path — seconds to minutes
HV->>G: allocate vCPU, vRAM, vDisk
G->>G: boot kernel, mount fs, run init
G->>G: finally, start the app
end
rect rgb(235, 245, 253)
note over E,K: Container path — milliseconds
E->>K: create isolated view (namespaces)
E->>K: apply resource limits (cgroups)
E->>K: exec the app process
end
Anchor these
- VM = fake hardware + real guest kernel. Container = real shared kernel + fake view.
- Nothing "boots" in a container — it's a process with a restricted worldview.
- Speed comes from sharing the kernel; the security trade-off comes from the same place.
See what actually stuck.
Take the practice scenarios now.