Docker has gained a lot of attention over the past several years. But not only because of its cool logo or it being the top buzzword of managers, but also because of its useful features. We talked about Docker quite a bit without really understanding why it’s so great to use. So we decided to take a closer look on how Docker actually works.
In this article, we want to shed some light on a few technologies used by Docker enabling it to be so lightweight and fast in startup compared to “traditional” virtual machines (VMs). Docker itself serves us as an example, you could replace it with any other container technology, for example LXC.
Reading this article requires some profound knowledge of virtualization. Terms like “guest system” or “hypervisor” should ring a bell. Also you should have heard of an operating system called Linux (it is probably running on your smartphone and you are waiting for an update).
So let’s go!
Don’t own – share
When you look at the fundamental differences between containers and VMs, you will notice two outstanding characteristics:
- VMs rarely share resources with other VMs running on the same host. This applies to almost every resource thinkable on a system. This is the reason why they are isolated so well against each other. But if you want to run several copies of one VM on one host, each VM will take up resources for itself. Take the kernel of the guest system for example: each guest has to burn a lot of resources by shipping and running its own kernel.
- Containers almost always share resources with other containers running on the same host. Therefore, the isolation against other containers is worse compared to that of VMs. But running several copies of the same container will cost you just a little more than running just one container because they share almost all their resources. Looking at the kernel again, you will notice, that each container is using the kernel of the host system, reducing its overhead compared to a traditional VM.
And with that said, you already understood the key principle of container technology: sharing resources. The only question remaining is: How can this be achieved in a fast, secure and lightweight way?
Creating a safe space
Traditional virtual machines run a complete guest operation system on the host operating system. The host system can be either a bare metal hypervisor abstracting the hardware, or it can be something like VirtualBox, where you run the guest system inside a fully functional host operating system. The execution of the guest system can be accelerated to a certain point using virtualization extensions on modern processors, but basically you have to run the entire guest operation system all the time.
With Docker, you use the host system as basis for your containers. The container itself is nothing more than a process running the specified application. The container processes running all your applications are separated against each other using Linux kernel features like namespaces and cgroups:
- Namespaces behave identically to variable scopes in programming languages. Everything created inside a namespace is visible to the namespace itself, but you can’t access resources created outside of your namespace. So, if you put your container process inside a namespace, it can use resources inside its own space, but it can’t access other containers. These resources can be network devices, mounted file systems or even users.
- Cgroups allow Docker to control the access to certain resources that need to be used by all containers: the CPU, memory and disk-IO. They ensure equal access to these resources for all containers.
This explains, how the different containers can be isolated against each other. However, the containers running on the same host are separated only by the host system kernel. So if your contained application gets attacked, it will be easier for the attacker to also get control over the host system, than having to hack the VM first and then the host.
Nevertheless it also explains why you can start a Docker container so much faster than a VM. If you start a VM, you have to boot an operation system, which takes some time (especially when you are in a hurry). If you start a container, you only need to start a process. This is as fast as starting any process which is almost instantly.
This explains why you can start Containers so fast. Next we will explain why containers need so little of your disk space.
File System Layering
If you currently installed a Linux system, for example Debian, it took probably 1 GB of your hard disk just for the minimal installation. But if you look at the size of a minimal Debian Docker container, it is only 150 MB.
But why is the Docker container so much smaller? The answer is, of course, because the container shares its files with your host.
This is achieved by using a layered file system like Unionfs. Layered file systems use a tree data structure to allow copy-on-write-operations on files. Whenever you change a file, a new branch of the file system is created, that contains the modified file. The old file is kept in the existing branch.
When you run a new Docker container, you create a new layer on the file system. All the files differing from those of the host system are copied and stored in this layer. So you only need storage capacity for the files you changed. All the unchanged default vanilla files, are read from your host. If you stop your container, all changes are potentially lost because you also shut down your branch of the file system. If you want to preserve this branch, you need to explicitly do so.
So if you are running a Linux based Docker container on a Linux host, you could benefit from the huge overlap of the two systems resulting in very small images. Most of the base images published on Docker Hub however overwrite a lot of your host system files, resulting in larger images again. Here you have to choose between having this convenient way to get your images and investing time to build your own, very small images.
A word on Windows
We have now talked at length about the technological background of Docker. But you never heard the word “Windows”. This is because Windows and Docker don’t go well together. All the presented techniques are based on the Linux kernel and its API. So far, there are no Windows-based Containers in the Docker Hub. They may also exist in the Windows kernel, but we can’t know for sure. Microsoft has announced they will also support Docker containers, but even so, it won’t be possible to run Linux containers on Windows or the other way around.
This brings us to our conclusion on the techniques used by Docker.
Final thoughts
Hopefully, after reading this article you know why Docker containers are so fast and lightweight. Mainly because they share a lot. This is very good from a resource management perspective, but can also be a hazard from a security point of view. You will have to decide for yourself, which of the two is more important. In an other article, we will talk about the security implications of Docker, and how you can protect yourself from bad containers.
If this article didn’t contain enough information for you or you are just very interested in this topic, here are some links for further reading:
Leave a Reply
You must be logged in to post a comment.