A few weeks back, Docker made waves in the container community when it announced it had purchased Unikernel Systems, creators of the MirageOS unikernel operating system. Although Docker had praised the unikernel for its small footprint, superior security, others had raised questions about how the technology would be used in production. “Unikernels are unfit for production,” blasted Joyent’s chief technology officer Bryan Cantrill, in a blog post, arguing that, because of their design, unikernels can’t be debugged.
To learn more about unikernels, we spoke with Lars Kurth, who is the chairman of the Xen Project Advisory Board. He is well-acquainted with the ideas around unikernels: MirageOS is a Xen subproject. He is also director of open source solutions for Citrix.
TNS: First of all, at a very high level, what is a unikernel, and how is it different from a container, or from a virtual machine, or a full-fledged operating system?
Kurth: Actually, that’s not such a simple question, because there’re a couple of different classes of unikernel. Fundamentally, it’s a single application wrapped-up and targeted at a specific runtime environment like a VM. So you’re basically using the hypervisor layer as an operating system.
On the one hand, we have projects such as the Xen Project’s MirageOS, which is single language unikernel. At the very bottom of a unikernel stack, you have a unikernel base, a very small thin layer that engages with the hypervisor or with the hardware directly. On top of the unikernel base, sits a very small language runtime layer, and a single application running on top of it.
Typically unikernels also have no processes and run in a single address space. Other unikernels such as RumpRun, are not tied to a specific language. RumpRun, for example, allows POSIX style applications to run as unikernels.
In some sense unikernels are a bit like Java Virtual Machines that run on x86, ARM or other native instruction sets.
One of the original design ideas behind JVMs was portability. And Java ME and its predecessors originally were intended to run on bare metal. So in some sense, a J2ME runtime for bare-metal environments is very similar to a unikernel base. Another parallel between unikernels and JVM is that within a JVM, you also only have one address space and no separation between kernel and user-space. Of course, that analogy is not 100 percent correct, but it does maybe provide another way to think about unikernels.
TNS: Interesting. So, in that regard, unikernals are like the JVM.
Kurth: There are certainly some similarities, but, of course, unikernels are different and exist for languages such as Haskell, OCaml, Erlang, Java and there is even a project now that targets C++11. And with languages such as Haskell and OCaml, you can also rely on the compiler or linker to eliminate all dead code, which is something you couldn’t do with a more dynamic language.
TNS: What does a data center need to run unikernels? Do you need some form of Linux and Xen?
Kurth: All you really need to run a unikernel—and that applies to all unikernels—is to have a unikernel base. As explained earlier, this is a very thin layer that exposes basic hardware functions (typically I/O) to the language run-time. We have two unikernel bases today in use for Xen: One is Mini-OS, and the other one is RumpRun.
Other people, like IBM, just started experimenting with a unikernel base for KVM called Solo5, but it’s all very early days. There are some challenges, for example with startup speed, which may not be easily solvable. But this whole idea is picking up momentum.
TNS: What other use-cases that you see would be particularly beneficial for unikernels? We’ve heard from Docker that two use cases would be for very small embedded systems and for very large distributed applications.
Kurth: I think you’re certainly right. It’s very interesting for those kinds of applications, and also in a world where applications are built from cooperating microservices. Unikernels provide one additional tool to architect such systems.
I’ve been working in an embedded context for a very long time before I moved to work into cloud computing and some of the ideas behind unikernels aren’t that different to traditional embedded software development.
Then, if you throw standardized tooling into the mix, such as provided by Docker, you get a standardized toolchain, which potentially can cover different market segments in a similar way. This is a very powerful idea. Of course, it will all depend on how this will be implemented, and how it works in practice. But the potential is there and could make life for many users and developers a lot easier. It might even break down silos between how different industry segments have traditionally approached software engineering.
TNS: Let’s talk about some of the tradeoffs. Like, I heard you have to port your applications to unikernels. How would that work?
Kurth: For some unikernels, you certainly have to write applications from scratch. However, for others (such as RumpRun), you fundamentally just take an existing application and compile it against a new unikernel. According to the developers, the biggest task of porting is removing functionality you don’t need.
The first step is to take a typical application (for example, NGINX) including all dependencies. Note that there may be hundreds of library dependencies. In a second step, you strip out the functions that you do not need. That is a manual process today, but could probably be automated. Then, of course, you have to test the end result.
TNS: What about debugging? Joyent’s Bryan Cantrill says you can’t debug unikernels…
Kurth: Right, as I understood his argument, Bryan claims that you have to have an operating system with processes to enable debugging. That is a very desktop-centric view of the world and also not strictly true.
If it were, you couldn’t debug anything deeply embedded or any IoT appliance. However, there are lots of examples that show that you can. You just have to build the right interface into the application you want to debug and then remotely connect to the debugged application.
At the end of the day, this can all be done. You just need to want to do it. It’s just an engineering problem. And it’s not actually that complex. Going back to the Java analogy, you debug a Java application, which runs on your phone from your desktop. All you need to do is have the appropriate Java debug agent built into your Java image.
In addition, most production code that is deployed has debug functionality disabled to minimize security risks. So having limited debug support in production environments is not that unusual.
TNS: So, it’s simply a case of the correct debugging tools being built out, like with any new technology.
Kurth: For a lot of the languages that unikernels support, the debug tools already exist. If you look at Haskell, there is a remote debugger package that you should, in theory, be able to use to debug a unikernel via a network connection. It may not work out of the box, but I believe that the lack of debug support in unikernels can be overcome.
Transcription by Mara Kruk
Docker, IBM, and Joyent are sponsors of The New Stack
Feature Image via Pixabay.