What’s the Difference Between Unikernels and Operating Systems?
This article is part of the TechXchange: VMs, Unikernels, and Containers
Virtualization technology, whereby multiple operating systems can be run on shared hardware, is extremely well understood if somewhat inefficient in its use of resources. Just a few decades ago, everyone used virtual machines (VM) to host and manage the infrastructure. More recently, industries have shifted toward containers and associated infrastructure such as Docker and Kubernetes.
Virtual Machines
The original virtualization architecture system was based on implementing a number of VMs. Every VM has to run its own instance of an operating system, resulting in a duplication of responsibility. It’s also hard to manage such an infrastructure, as there are multiple servers that are all independent VMs.
Containers try to achieve the same concept as virtual machines, but they eliminate duplication of effort between machines. Instead of loading an entire operating system for an app, Docker lets containers use the kernel of the host OS while allowing them to sideload app-specific libraries and programs. By adjusting the container and its image, it’s possible to fine-tune the specific libraries and configuration employed by one’s specific app. This results in performance gains without the overhead of running an entire OS.
Containers are easy to run on development machines. The deployment process itself also is much simpler since one just uploads pre-built containers to a container repository and production systems can pull the updated version.
However, the container-based approach has its downsides. The software must be adapted for usage in containers (containerized), which can get tricky, especially with legacy codebases. Containers have many more configurations for resource allocation and interop capabilities, so it’s quite easy to misconfigure them.
Unikernels
The next logical step in the progression from VMs to containers is unikernels, which further push the concept of containers. Unikernels are effectively a set of pre-built binary libraries. They’re specialized, single-address-space machine images constructed by using library operating systems. Unikernels provide the developer with components to pick from to build the minimal hardware interfacing layer. Stated otherwise, they employ the functions needed to make an application work, and nothing more.
Unikernels have less overhead than containers and are more streamlined, offering the potential for enhanced performance. Furthermore, eliminating the use of a multi-user, multiple address space kernel drastically improves security.
Several of the public-domain unikernels are tied to a specific compiler language such as runtime.js (javascript), Clive (Go), LING (Erlang), and Mirage (Ocaml). One, OSv, can run many language runtimes.
Still, a number of issues associated with unikernels have limited their applications—until now. These include:
- Producing unikernel images is complicated and requires deep knowledge on the subject.
- Current application frameworks must adapt and produce documentation on usage in unikernels.
- The lack of a safety-certifiable/certified unikernel for mission-critical applications,
Comparing an Operating System with a Unikernel
User mode vs. kernel mode
Unlike an operating system, unikernels run in user mode. At a high level, kernel mode is generally reserved for the lowest-level, most trusted functions of the operating system. Crashes in kernel mode are catastrophic; they will halt the entire system. In user mode, the executing code has no ability to directly access hardware or reference memory. A more detailed comparison of the two modescan be found here.
This is the fundamental reason we hear from the industry why the use of unikernels is being explored once again. Hardly a week goes by without a report of a cyberattack on critical infrastructure, an enterprise, or a federal business. The operating system is a point of weakness.
Resource allocation
Unlike an operating system, unikernels don’t handle resource allocation. The hypervisor manages direct hardware interoperation. All application-specific system calls are pushed as close to the app as possible. This is conducted in the hypervisor.
For secure systems, a type-1 hypervisor (where no underlying “helper” OS is present) that runs directly on hardware and loads virtual machines should be utilized. Hypervisors that rely on an underlying “Host OS” create a point of compromise and weakness inside systems, for the reason mentioned above. Thus, we believe it should be avoided.
Debugging
Since a unikernel has no OS running whatsoever, the approach of connecting directly to its shell and investigating doesn’t work.
Single process, single user
Significant overhead is involved when adding process management. There must be a way to start/stop/inspect a process, ensure inter-process communication, etc. Multiple users require authorization and authentication, resource isolation, and so forth. These aren’t necessary in a single-purpose application. This does mean that certain applications would be nigh-on-impossible to implement as unikernels.
In Lynx Software’s area of focus on aerospace and defense, for example, the use of ARCINC 653 libraries would be extremely challenging. We believe that the right path is to:
- Implement multiple single-process applications
- Deploy operating systems alongside unikernels, while ensuring systems are designed in a way where they mitigate the impact of infiltration of an OS instance.
Unikernel vs. Bare-Metal Development
While not the focus of this article, you may ask whether unikernels replace bare-metal development. In our opinion, the introduction of a unikernel reduces the number of use cases where companies need bare-metal applications. Unikernels can provide APIs (for example, Lynx’s product supports POSIX), which makes it simpler for developers to build applications.
That said, while the unikernel can significantly reduce the memory footprint of the software, there’s still a place for bare metal in dealing with specific single functions. It will continue to be dramatically more effective to implement a 500-line application as a bare-metal app (e.g., working with private keys) than implementing it as a unikernel.
Conclusion
Given they reduce attack surfaces, unikernels work best for applications requiring speed, agility, and increased security and certifiability, such as aircraft systems and critical infrastructure. Unikernels also are very well-suited as a component for mission-critical systems with heterogeneous workloads that need the coexistence of RTOS, Linux, unikernel, and bare-metal guests.
While existing open-source unikernel implementations haven’t been hindered by a lack of adequate functionality, and no clear path to safety certification and immature toolchains for debugging and producing images, the industry now has its first commercial unikernel with POSIX compatibility. It marks a major leap forward in the progression from VMs to containers.
Read more articles in the TechXchange: VMs, Unikernels, and Containers