The labs on this site need JavaScript to run. The same content is written out below.
Learn › Architecture and operations › Deployment and operations
Containers and virtual machines
Why are containers lightweight and quick to start?
When you start several copies of the same application, a virtual machine loads a whole operating system for every instance, while containers share the kernel of the host. Change the type and the number, and compare what gets loaded and how much memory is used. Also see what happens when you put a memory limit on a container.
Checked against documentation and standards · The Docker and Linux kernel documentation
Concepts in this lab
- Containers and images
- A container is a technology that packages an application with the things it needs to run and runs it in an environment isolated from other processes, while sharing the kernel of the host operating system. An image is a read-only template used to create a container, and it holds the application, libraries, and configuration. Running the same image greatly reduces problems caused by differences between environments.
- Containers versus virtual machines
- A virtual machine virtualizes hardware and runs a whole separate operating system installed on top of it. A container shares the operating system kernel of the host and isolates only the processes. So a container is lighter and starts faster than a virtual machine, but a virtual machine has a higher level of isolation.
- Namespaces and cgroups
- Linux kernel features that are used to implement containers. Namespaces separate what a process can see (the process list, the network, the file system, and so on) so that each one looks like an independent environment. cgroups limit the amount of resources, such as CPU and memory, that a group of processes can use.
Try these
- Default settings — 3 containers. They share the kernel of the host.
- The same thing as virtual machines — One more operating system is loaded for each instance.
- Increase to 6 — Virtual machines. The share taken by operating systems becomes 6 times as large.
- 6 containers — It grows only by as much as the application uses.
- Memory limit of 256MB — The application tries to use 400MB and is killed.
Running with the default settings
- The host operating system is running on one physical server. You want to start 3 application instances on it, isolated from each other.
- The container runtime does not create virtual hardware. It only runs processes in isolation, using features of the host kernel.
- Container 1: The image (a bundle of the application and the files it needs to run) is set up read-only, and a process is started on top of it. No operating system is booted, so it takes only as long as starting one process. Containers share the same image.
- Container 1: Running. Thanks to namespaces, this process appears to have its own file system, network, and process list, but in reality it is an ordinary process on the host kernel.
- Container 2: The image (a bundle of the application and the files it needs to run) is set up read-only, and a process is started on top of it. No operating system is booted, so it takes only as long as starting one process. Containers share the same image.
- Container 2: Running. Thanks to namespaces, this process appears to have its own file system, network, and process list, but in reality it is an ordinary process on the host kernel.
- Container 3: The image (a bundle of the application and the files it needs to run) is set up read-only, and a process is started on top of it. No operating system is booted, so it takes only as long as starting one process. Containers share the same image.
- Container 3: Running. Thanks to namespaces, this process appears to have its own file system, network, and process list, but in reality it is an ordinary process on the host kernel.
Result of this run
- Containers share the kernel, so they are lightweight and start quickly. In return, the isolation is weaker than that of a virtual machine, and they work only with the same kind of kernel as the host. Namespaces divide "what you can see," and cgroups divide "how many resources you can use."
Code
# Dockerfile
FROM eclipse-temurin:21-jre # a base image that includes a JRE
COPY build/libs/app.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
# Run (containers: 3)
$ docker run -d --memory=1024m my-app:1.0
Assumptions of this model
The memory figures (about 1GB for a guest operating system, about 400MB for the application) and the boot times are rough examples to show the direction of the difference, and the real values vary a great deal depending on the setup. That containers share the host kernel and are isolated with namespaces and cgroups, and that the kernel kills a process when it goes over its limit, follow the explanations in the Docker and Linux kernel documentation. Docker Desktop on Windows or Mac keeps one Linux virtual machine inside and runs the containers in it.
Previous lab: Deployment strategies · Next lab: Kubernetes self-healing