Running unikernels locally

Built in to kraft is a runtime manager which allows you to instantiate and manage multiple unikernel instances locally.

At present, kraft only supports running instances that target the KVM hypervisor either through QEMU or Firecracker. We plan on adding support for additional hypervisors including Xen, VMware and Hyper-V. For more information the progress of these hypervisors, you can track the relevant GitHub issue.

Learn more

Get the most out of your application and Unikraft

The only cloud platform scaling to zero, with 'only on' pricing, and cold-starting in 20ms.

There are multiple ways to instantiate a unikernel with kraft. The subcommand kraft run has been designed to be context-aware and can be used in different ways to launch unikernels depending on what is provided to it.

With the kraft run command, you are able to launch an instance using an underlying hypervisor solution. For example, kraft run will interface with QEMU directly to instantiate a unikernel.

In some circumstances, for example in nested virtualization environments, it may not be possible to access hardware-level instruction sets (ISAs) to execute the unikernel. In this scenario, hardware emulation will be used and it should be noted that this has a significant penalty on runtime performance of the application.

Running after building a project#

Following a successful build of a unikernel, you can simply invoke the following without any additional flags when cd'd within a project directory to preview the unikernel instance in action:

kraft run

For long-running applications, typing Ctrl + C will only detach you from the application's stdout. See more about stopping and removing the unikernel instance.

In the above example, the offical "Hello, world" application was run. It has multiple targets with varying platforms and architecture tuples. When kraft run was invoked, it intelligently detected information about the host system and suggested two possible targets based on the availability of QEMU on the system.

Running a Unikraft kernel binary image#

It is possible to pass directly to kraft run in its first positional argument the path to a binary image. In the example below, we execute a pre-built unikernel binary:

kraft run KERNEL

In the above example, the provided kernel matched the host's architecture. kraft will attempt to intelligently determine whether it can run the supplied unikernel binary and select the appropriate hypervisor.

Running a Linux userspace application (via a loader)#

Given a pre-built Linux userspace application, it is possible to execute this on top of Unikraft's ELF Loader Application in binary compatibility mode.

kraft run BINARY

In the above example, a pre-built ELF Loader application was dynamically downloaded and used to launch the pre-built helloworld binary.

You can set the path to the ELF Loader application, either as an OCI Image reference or to a path on disk to a kernel image via the --elfloader flag. For example, we provide an strace-like image which is packaged as an OCI image and available publicly at which is useful for debugging:

kraft run --elfloader BINARY

Running pre-built OCI-packaged images#

You can reference an OCI image unikernel as a positional argument with kraft run which, if not present on the host machine, will be downloaded before it is executed. For example, to build an execute the official "Hello, world!" application from Unikraft, you can run:

kraft run

Connecting a unikernel instance to a network#

In most cases, applications are intended to be accessible over a network. Built-in to kraft is a network manager which allows you to create, modify and remove networks of varying implementation types.

At present, kraft only supports networks on Linux based on bridge networking.

To view existing networks, simply run:

kraft net ls

To create a new network, specify the address and range in CIDR notation with the -n flag and a first positional argument representing the new network name:

kraft net create -n kraft0

The first address in the CIDR network will become the gateway. Once a network has been identified, you can attach this network to the unikernel instance with the -n|--network flag:

kraft run --network bridge:kraft0

In the above command, the --network flag requires both the underlying driver implementation name, driver, as well as the name of the network supported by the driver, in this case kraft0, separated by a colon :.

Forwarding exposed ports to your host#

Whilst -n|--network allows you to connect multiple unikernels to the same network, it can be also useful to simply port-forward from your host to a unikernel instance.

For example, when an NGINX unikernel exposes port 80 and you wish to map port 8080 on your localhost. You can use the -p flag to achieve this affect as follows:

kraft run -p 8080:80

In the above example, the NGINX instance will be available at http://localhost:8080/.

Rootfs and mounting volumes#

Learn more about mounting filesystems to the unikernel instance in our related rootfs documentation.

Supplying command-line arguments#

The unikernel instance essentially has two types of command-lines:

  1. Arguments which are supplied directly to Unikraft's core. These manipulate Unikraft itself and are used by kernel subsystems. For example, these include: environmental variables; statically defined networking parameters such as IP address and gateway; and, named volumes and their intended mount paths.
  2. Application-level command line arguments. These are intended for the application which is built as a unikernel, for example with NGINX this could be the -c flag which sets the path in the root filesystem to the configuration file.

To set command-line arguments for either Unikraft or the application is done as the second positional argument to kraft run or via the -a flag:

kraft run -c /nginx/conf/nginx.conf

To set command-line arguments for Unikraft, you simply need to separate with two dashes as a delimeter --, for example:

kraft run netdev.ipv4_addr= -- -c /nginx/conf/nginx.conf

Viewing unikernel instances#

To view the state of previously instantiated unikernel instances you can use the following:

kraft ps
beautiful_bintijua project://helloworld 1 hour ago exited 64M qemu/x86_64
elastic_guy oci:// 2 hours ago running 64M qemu/x86_64

The above command will display a ps-like output which displays the name, the "source" of the unikernel (whether from a project context, a binary context, an ELF Loader context or an OCI image context), any command-line arguments supplied to it, when it was created, its state, how much memory was assigned to the instance, and which platform/architecture it is.

To view more detailed information about all instances, supply the --long flag:

kraft ps --long

Possible states of a unikernel instance are:

unknownThe instance's state could not be determined.
createdThe instance has been created but not started.
failedThe instance could not be created.
restartingThe instance is in the process of rebooting.
runningThe instance is active and executing.
pausedThe instance has been paused and is no longer executing.
exitedThe instance has gracefully exited (whether successful or not.)
erroredThe instance has non-gracefully exited, e.g. crashed or panicked.

Stopping and removing unikernel instances#

To stop an instance that is actively executing, you simply need to reference its name which was either automatically generated or set via the -n|--name flag:

kraft stop NAME

To stop all actively executing instances, you can simply pass the --all flag:

kraft stop --all

To remove a specific instance:

kraft rm NAME

And to remove all instances, similarly pass the --all flag:

kraft rm --all

Running kraft rm will gracefully stop the unikernel instance(s) before it is removed.

Edit this page on GitHub

Connect with the community

Feel free to ask questions, report issues, and meet new people.

Join us on Discord!

Getting Started

What is a unikernel?Install CLI companion toolUnikraft InternalsRoadmap

© 2024  The Unikraft Authors. All rights reserved. Documentation distributed under CC BY-NC 4.0.