Skip to content

Unikernel support🔗

Unikernels are specialized, minimalistic operating systems constructed to run a single application. By compiling only the necessary components of an OS into the final image, unikernels offer improved performance, security, and smaller footprints compared to traditional OS-based virtual machines.

One of the main goals of urunc is to bridge the gap between unikernels and the cloud-native ecosystem. For that reason, urunc aims to support all the available unikernel frameworks and similar technologies.

For the time being, urunc provides support for Unikraft and Rumprun unikernels.

Unikraft🔗

Unikraft is a POSIX-friendly and highly modular unikernel framework designed to make it easier to build optimized, lightweight, and high-performance unikernels. Unlike traditional monolithic unikernel approaches, Unikraft allows developers to include only the components necessary for their application, resulting in reduced footprint and improved performance. At the same time, Unikraft offers Linux binary compatibility allowing easier and effortless execution of existing applications on top of Unikraft. With support for various programming languages and environments, Unikraft is ideal for building unikernels across a wide range of use cases.

VMMs and other sandbox monitors🔗

Unikraft can boot on top of both Xen and KVM hypervisors. Especially in the case of KVM, Unikraft supports Qemu and AWS Firecracker. In both cases, it gets network access through virtio-net. In the case of storage, to the best of our knowledge Unikraft supports two options: a) 9pFS sharing a directory between the host and the unikernel and b) initrd and therefore an initial RamFS.

Unikraft and urunc🔗

In the case of Unikraft, urunc supports both network and storage I/O over both Qemu and Firecracker VMMs. However, for the time being, urunc only offers support for the initrd option of Unikraft and not for shared-fs. On the other hand, the shared-fs option is Work-In-Progress and we will soon provide an update about this.

Unikraft maintains a catalog with available applications as unikernel images. Check out our packaging page on how to get these images and run them on top of urunc.

An example of Unikraft on top of Qemu with urunc:

$ sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/nginx-qemu-unikraft-initrd:latest unikernel

Another example of Unikraft on top of Firecracker with urunc:

$ sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/nginx-firecracker-unikraft-initrd:latest unikernel

Mirage🔗

MirageOS is a library operating system that constructs unikernels for secure, high-performance network applications across various cloud computing and mobile platforms. MirageOS uses the OCaml language, with libraries that provide networking, storage and concurrency support that work under Unix during development, but become operating system drivers when being compiled for production deployment. We can easily set up and build MirageOS unikernels with mirage, which can be installed throgu the Opam source package manager. The framework is fully event-driven, with no support for preemptive threading.

MirageOS is characterized from the extremely fast start up times (just a few milliseconds), small binaries (usually a few megabytes), small footprint (requires a few megabytes of memory) and safe logic, as it is completely written in OCaml.

VMMs and other sandbox monitors🔗

MirageOS, as one of the first unikernel frameworks, provides support for a variety of hypervisors and platforms. In particular, MirageOS makes use of Solo5 and can execute as a VM over KVM/Xen and other OSes, such as BSD OSes (FreeBSD, OpenBSD) or even Muen. Especially for KVM, MirageOS supports Qemu and Solo5-hvt. It can access the network through virtio-net in the case of Qemu and using Solo5's I/O interface in the case of Solo5. For storage, MirageOS supports block-based storage through virtio-block and Solo5's I/O in Qemu and Solo5 respectively.

Furthermore, MirageOS is also possible to execute on top of Solo5-spt a sandbox monitor of Solo5 project that does not use hardware-assisted virtualization. In that context, MirageOS can access network and block storage through Solo5's I/O interface.

MirageOS and urunc🔗

In the case of MirageOS urunc provides support for Solo5, Solo5 and Qemu. For all monitors of Solo5 urunc allows the access of both network and block storage through Solo5's I/O interface and for Qemu through virtio-net and virtio-block.

For the time being, the block image that the MirageOS unikernel access during its execution should be placed inside the container image.

For more information on packaging MirageOS unikernels for urunc take a look at our packaging page.

An example of MirageOS on top of Solo5 using a block image inside the container's rootfs with 'urunc':

$ sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/net-mirage-hvt:latest unikernel

An example of MirageOS on top of Solo5 with 'urunc':

$ sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/net-mirage-spt:latest unikernel

Rumprun🔗

Rumprun is a unikernel framework based on NetBSD, providing support for a variety of POSIX-compliant applications. Rumprun is particularly useful for deploying existing POSIX applications with minimal modifications. As a consequence of its design Rumprun can be up-to-date with the latest changes of NetBSD. However, the current repositories are not totally up-to-date. The repository with the most recent NetBSD version is here.

In addition, Rumprun maintains a repository with all ported applications that can be easily used on top of Rumprun.

VMMs and other sandbox monitors🔗

Rumprun, as one of the oldest unikernel frameworks, provides support for both Xen and KVM hypervisors. Especially in the case of KVM, Rumprun supports Qemu and Solo5-hvt. It can access the network through virtio-net in the case of Qemu and using Solo5's I/O interface in the case of Solo5. As far as we concern, Rumprun only supports block storage through virtio-block and Solo5's I/O in Qemu and Solo5 respectively.

Furthermore, Rumprun is also possible to execute on top of Solo5-spt a sandbox monitor of Solo5 project that does not use hardware-assisted virtualization. In that context, Rumprun can access network and block storage through Solo5's I/O interface.

Rumprun and urunc🔗

In the case of Rumprun, urunc provides support for Solo5 and Solo5, but not yet for Qemu. For all monitors of Solo5 urunc allows the access of both network and block storage through Solo5's I/O interface. In particular, urunc takes advantage of Rumprun block storage and ext2 filesystem support and allows the mounting of the containerd's snapshot directly in the unikernel. This is only possible using devmapper as a snapshotter in containerd. For more information on setting up devmapper, please take a look on our installation guide.

Except for devmapper, urunc also supports the option of adding a block image inside the container image and attaching it to Rumprun.

For more information on packaging Rumprun unikernels for urunc take a look at our packaging page.

An example of Rumprun on top of Solo5 using a block image inside the container's rootfs with 'urunc':

$ sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/redis-hvt-rumprun-block:latest unikernel

An example of Rumprun on top of Solo5 using devmapper with 'urunc':

$ sudo nerdctl run --rm -ti --snapshotter devmapper --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/redis-spt-rumprun:latest unikernel

Mewz🔗

Mewz is a unikernel framework written from scratch in Zig, targeting WASM workloads. In contrast to other WASM runtimes that execute on top of general purpose operating systems, Mewz is designed as a specialized kernel where WASM applications can execute. In this way, Mewz provides the minimal required features and environment for executing WASM workloads. In addition, every WASM application executes on a separate Mewz instance, maintaining the single-purpose notion of unikernels.

According to the design of Mewz, the WASM application is transformed to an object file which is directly linked against the Mewz kernel. Therefore, when the Mewz kernel boots, it executes the linked WASM application. Mewz has partial support for WASI and it provides support for networking and an in-memory, read-only filesystem. In addition, Mewz has socket compatibility with WasmEdge,

A few examples of Mewz unikernels can be found in the examples directory of Mewz's repository.

VMMs and other sandbox monitors🔗

Mewz can execute only on top of Qemu. It can access the network through a virtio-net PCI device. In the case of storage, Mewz only supports an in-memory read-only filesystem, which is directly linked along with the kernel.

Mewz and urunc🔗

In the case of Mewz, urunc provides support for Qemu. If the container is configured with network access, then urunc will use a virtio-net PCI device to provide network access to Mewz unikernels.

For more information on packaging Mewz unikernels for urunc take a look at our packaging page.

An example of Mewz on top of Qemu with 'urunc':

$ sudo nerdctl run -m 512M --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/hello-server-qemu-mewz:latest

Note: As far as we understand, Mewz requires at least 512M of memory to properly boot.

Linux🔗

Linux is maybe the most widely used kernel and the vast majority of servers in the cloud use an OS based on Linux kernel. As a result, most applications and services we run on the cloud are built targeting Linux. Of course, Linux is not a unikernel framework. However, thanks to its highly configurable build-system we can create very small, tailored Linux kernels for a single application. The concept was introduced by the Lupine project, which examined how we can turn the Linux kernel into a unikernel.

Using Linux, we can execute the vast majority of the existing containers on top of urunc. However, the rational is to target single application containers and not fully-blown distro containers. Focusing on a single application, we can further minimize the Linux kernel and keep only the necessary components for a specific application. Such a design allows the creation of minimal and fast single-application kernels that we can execute on top of urunc.

VMMs and other sandbox monitors🔗

Linux has wide support for different hardware and virtualization targets. It can execute on top of Qemu and Firecracker. It can access the network and storage through various ways (e.g. paravirtualization, emulated devices etc.).

Linux and urunc🔗

Focusing on the single-application notion of using the Linux kernel, urunc provides support for both Qemu and Firecracker. For network, urunc will make use of virtio-net either through PCI or MMIO, depending on the monitor. In the case of storage, urunc uses virtio-block and initrd. In particular, urunc takes advantage of the extensive filesystem support of Linux and can directly mount containerd's snapshot directly to a Linux VM. This is only possible using devmapper as a snapshotter in containerd. For more information on setting up devmapper, please take a look on our installation guide.

For more information on packaging applications and executing them on top of Linux with urunc take a look at our running existing containers tutorial.

An example of a Nginx alpine image on top of Qemu and Linux with 'urunc' and devmapper as a snapshotter:

$ sudo nerdctl run --rm -ti --snapshotter devmapper --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/nginx-qemu-linux:latest

An example of a Redis alpine image transformed to a block file on top of Firecracker and Linux with 'urunc':

$ sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/redis-firecracker-linux-block:latest

Future unikernels and frameworks:🔗

In the near future, we plan to add support for the following frameworks:

OSv: An OS designed specifically to run as a single application on top of a hypervisor. OSv is known for its performance optimization and supports a wide range of programming languages, including Java, Node.js, and Python.