Introduction to Unikernels and Unikraft

Unikraft is a Unikernel Development Kit and consists of an extensive build system in addition to core and external library ecosystem which facilitate the underlying functionality of a unikernel. It is built as an open-source project and does so in the context of a vibrant community consisting of highly skilled software engineers, researchers, teachers, students and hobbyists. As a community, its outreach consists of over 50 active contributors, 12 peer-reviewed academic publications, in 10 institutes, in 6 countries.

To find out more about Unikraft, checkout the documentation and join Discord. Please also star the main Unikraft repository.

Prerequisites

You should have basic knowledge of the following items:

  • Linux CLI: working with the filesystem, running commands, documentation
  • C programming language
  • Git: a very good tutorial on Git is Git Immersion
  • GitHub
  • Operating system concepts (processes, memory management, working with files, networking)
  • virtualization

Setup

We encourage you to form teams of 3-4 people and work together during the:

  • tutorials: first day (Wednesday, May 10, 2023)
  • hackathon challenge: second day (Thursday, May 11, 2023)

Resources

For this hackathon, you require a native Linux environment and / or virtual machine.

You need to install required packages. On a Debian/Ubuntu-based setup, use the commands below to install required packages:

$ sudo apt -y update
$ sudo apt -y install sudo
$ sudo apt -y install vim
$ sudo apt -y install less
$ sudo apt -y install ca-certificates
$ sudo apt -y install --no-install-recommends \
            build-essential \
            libncurses-dev \
            libyaml-dev \
            flex \
            git \
            wget \
            socat \
            bison \
            unzip \
            uuid-runtime \
            python3 \
            qemu-kvm \
            qemu-system-x86 \
            sgabios

If a native Linux environment is not available, you can use this virtual machine. It’s in OVA format, import it in VirtualBox or VMware or any other OVA-supporting virtualization solution.

As a backup, we provide virtual machines where everything is setup. They are available on UPB Guacamole infrastructure. Please see the hack-porto23 channel on Discord for instructions on accessing the virtual machine. You will require a computing system with a browser and an SSH client and that should be it.

We also have a Docker setup prepared that you can use. Make sure you have Docker installed. Grab the Docker container by running:

$ docker pull index.unikraft.io/unikraft.org/hackathons/base:latest

You can then run an instance using:

$ docker run --rm -it index.unikraft.io/unikraft.org/hackathons/base:latest /bin/bash

Inside the container you have all packages and setup required to setup and build Unikraft images. Running (via QEMU) is still recommended to happen outside the Docker container.

Setup Checks

First and foremost, access the virtual machine.

Secondly, list files. You would get something like:

[email protected]:~$ ls
docs/  packages/  scripts/

[email protected]:~$ tree -L 2
.
|-- docs
|   |-- content
[...]
`-- scripts
    |-- LICENSE
    |-- README.md
    |-- make-based
[...]

A quick description of the contents:

  • scripts/ is a directory that contains scripts used for building and running Unikraft applications.
  • docs/ is the directory where some sessions tasks will reside, it is a clone of the Unikraft docs repository.

Thirdly, do the steps below:

Run Unikraft helloworld

To easly setup, build and run the Unikraft helloworld application we provided some scripts that do all the work for you. Run the commands below to configure, build and run the Unikraft helloworld program. We will get into what the scripts do behind the scenes in the next session.

$ cd scripts/
$ cd make-based/app-helloworld/
$ ./do.sh setup    # <- this will clone all the dependencies in the `../../workdir` directory
Cloning into '../../workdir/unikraft'...
remote: Enumerating objects: 17633, done.
remote: Counting objects: 100% (682/682), done.
[...]

$ ./do.sh build    # <- this will invoke the Unikraft build system
make[1]: Entering directory '/home/stefan/.unikraft/unikraft'
LN      Makefile
MKDIR   lxdialog
CP      config
MKDIR   lxdialog
LN      helloworld_kvm-x86_64.dbg.gdb.py
[...]

$ ./do.sh run      # <- this will run the application that was build on the previous step, using `qemu`
SeaBIOS (version 1.13.0-1ubuntu1.1)
Booting from ROM..Powered by
o.   .o       _ _               __ _
Oo   Oo  ___ (_) | __ __  __ _ ' _) :_
oO   oO ' _ `| | |/ /  _)' _` | |_|  _)
oOo oOO| | | | |   (| | | (_) |  _) :_
 OoOoO ._, ._:_:_,\_._,  .__,_:_, \___)
                  Janus 0.11.0~422ceb47
Hello world!
Arguments:  "build/helloworld_kvm-x86_64"

Run Unikraft httpreply

With the same set of scripts, we can build and run the httpreply Unikraft application.

$ cd ~
$ cd scripts/
$ cd make-based/app-httpreply/
$ ./do.sh setup    # <- this will clone all the dependencies in the `../../workdir` directory
Cloning into '../../workdir/unikraft'...
remote: Enumerating objects: 17633, done.
remote: Counting objects: 100% (682/682), done.
[...]

$ ./do.sh build    # <- this will invoke the Unikraft build system
make[1]: Entering directory '/home/stefan/.unikraft/unikraft'
LN      Makefile
MKDIR   lxdialog
CP      config
MKDIR   lxdialog
LN      httpreply_kvm-x86_64.dbg.gdb.py
[...]

$ ./do.sh run      # <- this will run the application that was build on the previous step, using `qemu`
Booting from ROM..1: Set IPv4 address 172.44.0.2 mask 255.255.255.0 gw 172.44.0.1
en1: Added
en1: Interface is up
Powered by
o.   .o       _ _               __ _
Oo   Oo  ___ (_) | __ __  __ _ ' _) :_
oO   oO ' _ `| | |/ /  _)' _` | |_|  _)
oOo oOO| | | | |   (| | | (_) |  _) :_
 OoOoO ._, ._:_:_,\_._,  .__,_:_, \___)
                  Janus 0.11.0~422ceb47
Listening on port 8123...

The setup step will create a virtual bridge to enable communication with the unikernel. To test that the application works properly, we can run from another terminal:

$ wget 172.44.0.2:8123
--2023-03-30 07:56:30--  http://172.44.0.2:8123/
Connecting to 172.44.0.2:8123... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘index.html’

index.html              [ <=>                ]     159  --.-KB/s    in 0s

2023-03-30 07:56:30 (10,5 MB/s) - ‘index.html’ saved [159]