Containerization is the practice of packaging an application together with its dependencies, such as libraries, runtime, and configuration, into a single isolated unit called a container. Docker’s documentation describes containers as lightweight units that contain everything needed to run an application, so the application does not depend on what happens to be installed on the host machine.
Unlike a virtual machine, a container does not include a full guest operating system. Instead, containers running on the same host share that host’s operating system kernel. This makes them much lighter and faster to start than virtual machines, while still keeping applications isolated from one another.
The isolation that makes containers possible comes from features built into the Linux kernel. Namespaces, documented in the Linux manual, wrap a global system resource so that processes inside a namespace appear to have their own isolated instance of it, covering things like process IDs, networking, and filesystem mounts. Control groups, or cgroups, documented in the kernel itself, organize processes hierarchically and limit and account for the resources, such as CPU and memory, that a group of processes can use.
Tools like Docker combined these kernel features into an easy-to-use package, and orchestrators like Kubernetes built on top of containerization to run and coordinate many containers across clusters of machines. Together these made containerization a foundation of modern cloud-native software.