Containers vs Virtual Machines

Two Ways to Isolate Software

Before containers, the standard way to give an app "its own machine" was a virtual machine (VM): software that pretends to be an entire physical computer - a virtual CPU, virtual disk, virtual network card - and boots a full guest operating system (with its own kernel, the core program that talks directly to hardware) on top of that pretend hardware. It works, but it's heavy: booting a whole OS takes real time and real memory, every single time you start one.

A container takes a completely different shortcut. It doesn't pretend to be a computer at all - it's just an ordinary program (a process, the same kind of thing as a running text editor or web browser) on the host machine, given the illusion that it's alone on its own system. Two Linux kernel features create that illusion:

Analogy: Namespaces are like giving someone a private office with frosted-glass walls - they can only see their own desk, not the rest of the building, even though they're in the very same building as everyone else. cgroups are like a metering valve on that office's water and electricity - they can use what they're allotted, no more.
VM:         App → Guest OS (full kernel) → Hypervisor → Host OS → Hardware
Container:  App → Container runtime → Host OS (shared kernel) → Hardware
Virtual MachineContainer
Boots inminutesmilliseconds
Sizegigabytesmegabytes
Kernelits ownshared with host
Isolationvery strong (hardware-level)good (kernel-level)
Density per hosttenshundreds
Note: Containers share the host kernel. That's why they start instantly and stay tiny - and also why container security matters: a kernel exploit inside a container threatens the host. (More in the Security module.)
Tip: It's not either/or in real infrastructure - cloud providers typically run your containers inside VMs, combining VM isolation between customers with container speed for deployment.