Docker is not a VM. Neither is it a lightweight VM. But what’s the difference? My dockerfile needs an image of an OS (e.g. Ubuntu) to run, and virtual machines (such as VirtualBox) requires an image of an OS to also run, and both produce similar runtime environments for me to run the code in. Don’t they do the same thing?
The difference is what resources they virtualize.
Hypervisors & Virtual Machines in 30s
Hypervisors (Virtual Machine Managers) emulate hardware resources. They create virtual copies of the underlying machine (hence virtual machines 😉) They allow multiple operating systems to be run at the same time, isolated from one another.
Guest operating systems running on top of a hypervisor get the illusion that the hardware resources (disk, cpu) belongs to them completely, but the hypervisor works as an invisible middleman to the hardware, intercepting requests for hardware resources from different guest operating systems and serving them.
Docker & userlands in 30s
Docker containers emulate userspace environments. They allow multiple userland processes to be run at the same time, isolated from one another with their own userland environements. All of these processes share the host operating system i.e. host kernel.
The userland environment (container) includes a minimal filesystem /, /etc, /bin, /lib
with userland tools e.g. /bin/bash
. Dependencies that are installed on the environment such as RUN apt-get install -y openssl
are installed specific to that environment1. Less dependency hell2 for the developer!
Docker is able to isolate these environments through Linux kernel features such as namespaces
. The Docker daemon manages the lifetime of running userland environments, but does nothing to manage how the processes in the environment talk to the host kernel.
Similarities, Differences, Confusion
The reason why Docker and VM gets confused is because both technologies emulate something that gives the effect of a common runtime environment, with isolation of these environments. The difference lies in what the runtime environment is.
VMs provide isolated environments for Operating Systems and manages hardware resource access. Docker provides isolated environments for userland environments and manages the environment lifecycle.
VMs do alot more than containers, which is why containers are much faster than VMs. But containers will not solve all compatability issues…
A note on syscalls, compatability and the need for VMs
Docker doesn’t actually provide full cross-os compatability. It may seem possible at first, since Docker can be run on Windows OS
to run an Ubuntu
container. But this is a misconception!
To reiterate, Docker containers still interact with the host kernel. When a container does syscalls like open()
or write()
,
it actually calls those syscalls to talk to the host kernel.
Windows has very different kernel API compared to Linux. open()
in Linux != open()
in Windows. Things will crash and burn.
The reason why Docker on Windows works is because of WSL. It acts like a ‘lightweight vm’ to actually run the linux kernel. For containers running on the WSL ‘Linux VM’ on Windows, Linux syscalls like open()
actually exist since the Linux kernel is the underlying OS in the POV of the container. The Linux Kernel here is a ‘guest OS’ and does the whole shebang to actually access hardware resources.
Matrix-level shit, man…
So, perhaps VMs are not slow bloated useless things compared to containers.