Everybody in the IT world has heard the word container at this point. But containers are not the only way to isolate and deploy software. In this post we want to take give a high-level introduction to containers as well as virtual machines and unikernels.
For now, we focus on cloud computing. In cloud computing, you have central providers of compute infrastructure (e.g. Amazon, Microsoft, etc.) and anybody can rent a share of those resources to run their own software on. The challenge here is now, that the cloud provider must ensure, that no customer has access to the data and software of another customer.
The classical approach here are virtual machines (VMs). A virtual machine emulates a computer and the user then can install its own operating system (e.g. Linux) inside the VM and then run software there. A VM provides a high level of isolation, as the only way to interact with the host is a limited set of hypervisor calls. However, this approach has two downsides: First, it is often uncomfortable, as the user has to configure the environment by hand. Solutions to provision virtual machines exist, but they come with their own limitations and restrictions. Second, it introduces overhead in terms of CPU usage (the virtualization has its own costs) and in terms of disk space (a whole operating system has to be installed for every virtual machine).
Figure 1: Virtual Machines
A new approach has become extremely popular in the last decade (even though the technology is way older than that): Containers.
When using containers, the operating system of the computer is responsible for the isolation of the processes. For instance, processes in a container are only granted access to certain files and all processes are completely hidden outside the container. You could say that for a container, we don’t separate the systems on the hardware level as for the virtual machines, but on the operating system level (therefore it is also called OS-layer virtualization).
Containers have a lower overhead compared to VMs. You don’t have to emulate the hardware and you don’t have to run two operating systems. You also save disk space. Not only for the kernel, but also for data, as all the other data can be stored on the host’s file system as regular files, which is more efficient than emulating a hard disk.
Figure 2: Containers
Therefore, containers gained an immense traction in the past years, but one drawback remains. If a software could exploit the interface to the host OS and gain access to it, then all containers on that machine could be compromised. Luckily that interface seems to be quite solid so far.
A new third approach exists: Unikernels (also called library OS). The promise here is to improve the isolation compared to containers, whilst maintaining a higher performance than VMs and a low resource impact. At the moment, it is not widely used in the industry but it stands out more as an academic topic. However, we do think that there are plenty of areas where the advantages of unikernels can shine.
How does this work? You basically take your software and statically link it with the unikernel library. That library contains code which provides all the functionality that an operating system usually has, like booting, network, file system interface, multithreading etc. But that code is linked with the application, so that stuff like system-calls which normally introduce overhead get reduced to simple function calls.
Figure 3: Unikernels
The clue is that the resulting binary is now run in a virtual machine and profits are gained from all the isolation mechanisms we have for these, but without the overhead of the encapsulated operating systems. You could say that a unikernel enables an application to run “bare-metal”.
Let’s summarize the presented approaches (on a high level) in the following table.
|Virtual Machine||+||– – –||+++|
Of course this is only scratching the surface and reality is way more complex. We also ignored a lot of the factors that come into play when choosing a suitable technology. But if we could catch your interest in unikernels; We are developing a unikernel ourself and in IoT-NGIN we are investigating methods to make them more compatible with Container infrastructure, but this will be covered in another post.