-
Notifications
You must be signed in to change notification settings - Fork 3
Home
For this tutorial you need a KVM and a Xen host in order to run Unikraft. We have prepared a pair of hosts for you to play with. Get login data from the tutorial staff.
- When using Linux, you can simply login to your machine pair with:
ssh [email protected] -p <PORT>
- Windows users can use PuTTY to do a login. Set the hostname to
ucc-unikraft.nlehd.de
and the port according to your coupon. You should get asked for the username (typeroot
) and password when opening the connection.
You can easily build Unikraft Unikernels on your Linux host. If you have all tools and libraries installed to compile a Linux kernel you are ready to do this with Unikraft, too. Alternatively, you can directly compile Unikraft on the testing infrastructure that you got access too. It has compiler, tools, and necessary libraries pre-installed.
A Unikraft build is mostly consisting of a combination of multiple repositories. We differentiate them into: (1) Unikraft, (2) external libraries, (3) application. The build system assumes them organized in the following structure as default:
my-workspace/
├── apps/
│ └── helloworld/
│ └── webserver/
├── libs/
│ ├── lwip/
│ └── newlib/
└── unikraft/
Clone the following repositories with Git (git clone <URL> <DESTINATION PATH>
):
- Unikraft base repository directly under your workspace root: Use this fork of the upstream repo for this tutorial.
- External libraries into a
libs
subdirectory:- newlib: upstream repo. Please checkout the
staging
branch:
- newlib: upstream repo. Please checkout the
$ git checkout staging
- lwip: Use this fork of the upstream repo
- Applications into a
apps
subdirectory:- helloworld: upstream repo
- webserver: GitHub
Make sure that the directory structure under your workspace is exactly the same as shown in the overview ahead (e.g., call the folder of the cloned Unikraft repository unikraft
)
After you cloned the repos, go to the helloworld
application and run make menuconfig
for running the configuration. Unikraft uses the same configuration system as the Linux kernel (Kconfig). We will build Unikraft images for Xen, KVM, and Linux, so first step would be to go to Platform Configuration
menu and make the following changes:
- select
Xen guest image
- select
KVM guest
- select
Linux user space
UnderLibrary configuration
we also need to choose a scheduler: selectukschedcoop
.
Afterwards, save your configuration and build the image with typing make
. The build system will create three binaries, one for each platform:
$ ls -sh build/
[...]
88K helloworld_kvm-x86_64
40K helloworld_linuxu-x86_64
72K helloworld_xen-x86_64
[...]
Lets execute our Unikernel.
- The easiest is the one that we built as Linux user space application. It should execute on any Linux environment (your Linux machine, or on the machine pair we gave you):
$ build/helloworld_linuxu-x86_64
Welcome to _ __ _____
__ _____ (_) /__ _______ _/ _/ /_
/ // / _ \/ / '_// __/ _ `/ _/ __/
\_,_/_//_/_/_/\_\/_/ \_,_/_/ \__/
Titan 0.2~10ce3f2
Hello world!
- You can execute the KVM image (
helloworld_kvm-x86_64
) on the KVM host. If you did not build the image on your KVM host, eitherscp
it over or build it there again. For simplification we deployed a script there to start the virtual machine quickly:
$ kvm-guest -k helloworld_kvm-x86_64
With the -D
parameter you can have a look to the qemu
command line that is generated by the script.
- The procedure for Xen is similar. Get the Unikernel image on the Xen host and start the virtual machine there:
$ xen-guest -k helloworld_xen-x86_64
The parameter -D
is showing you the generated xl
machine configuration by the script.
After Hello world!
is printed, our Unikernel is shutting down directly. We do not have a chance to see that a VM was actually created, so lets modify the source code. Open main.c
your favorit editor (nano
, vim
, emacs
) and add the following busy loop accordingly within the main
function:
for (;;);
Rebuild the images with make
and execute them. The shell prompt should not return. With a second shell your can check that the Unikernel is still executing:
- Use
top
orhtop
for Linux and KVM. - Use
xl top
in Xen.
Note: You can terminate the KVM and Linux Unikernel with CTRL
+ C
. For xen-guest
it is CTRL
+ ]
.
The helloworld
application uses a very minimalistic libc
implementation called nolibc
. It is small but also quiet limited in terms of functionality. nolibc
is part of the Unikraft base repository and because of this it is called an internal library. They are located within the lib
directory of Unikraft.
In order to enhance the functionality provided by the Unikraft, external libraries can be added to the build. In the following we want to exchange nolibc
with newlib
, a standard libc implementation that you can find in various Linux distributions and embedded environments.
We need to add newlib to the library includes. Edit the Makefile
of the helloworld
application. Please type make properclean
before. This will delete the build directory (but not your configuration) and will force a full rebuild later.
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
UK_ROOT ?= $(PWD)/../../unikraft
UK_LIBS ?= $(PWD)/../../libs
-LIBS :=
+LIBS := $(UK_LIBS)/newlib
all:
@make -C $(UK_ROOT) A=$(PWD) L=$(LIBS)
When we do now make menuconfig
, newlib
appears in the Library Configuration
menu. Select it, and select also vfscore
(unfortunately this dependency is currently not automatically selected in the upstream repository). Afterwards type make
. Unikraft's build system will download the newlib's sources and build it together with all the other Unikraft libraries and application. Our newlib
repository consists only of glue code that is needed to port newlib
to the Unikraft.
You will notice that the built Unikernels are bigger than before. Try to run them again.
Debugging a Unikernel can be similarly done as debugging an application. In the following we are looking into print-based debugging and GDB.
Unikraft provides support for debug printing with the internal libukdebug
library. Code needs to be instrumented but the advantage is that the library automatically removes all print calls as soon as you disable debug printing.
We enable them by going to Library Configuration
and ukdebug
. Here we can change the logging level but also enable or disable various types of additional debugging features (e.g., assertions).
- Change
Debug message level
to have theShow all types of debug messages
value - Enable
Print bottom address of stack in debug messages
- Change
Message redirection
to have theKernel messages on debug output
value
With support from the virtualization platform and its toolstack (e.g., qemu
on KVM, xl
on Xen), a gdb
process can be attached to the instances. In the following we will try it out with Xen:
As first, we must ensure that debug symbols are generated when building Unikraft. For this you have to run make menuconfig
again and go to the Build Options
menu. The following needs to be changed:
-
Optimization level
: No optimizations -
Debugging information
:-
Debug information level
: Level 3
-
- Unselect
Strip final image
Typemake clean
and thenmake
. We want to make sure that every object file is rebuild with debugging information.
Start the a guest on a Xen host in paused state and enable the GDB server option:
$ xen-guest -k build/helloworld_xen-x86_64 -g 9999 -P
On a second terminal, attach gdb
to the virtual machine:
$ gdb --eval-command="target remote :9999" build/helloworld_xen-x86_64
You can now set a breakpoint to main()
and start the VM:
As last task, we are going to build a small webserver that replies with a single page. It is using lwip
for creating a socket and accepting incoming connections. Go to the webserver
application directory. Have a look to webserver.c
: It is a really short program and looks the same as you would write it for Linux. Its dependencies are defined within Config.uk
. Having this, there is actually not much left to configure. Mandatory options are locked in make menuconfig
. We just need to select our target platforms, select network drivers, save the config, and type make
.
For now, we support virtio for networking only (but more is coming). You can enable the driver by going to the KVM platform configuration and select Virtio PCI device support
and Virtio Net device
.
The image can be started on the KVM host. Remember to add a virtual network device attached to the bridge virbr0
:
$ kvm-guest -k build/webserver_kvm-x86_64 -b virbr0
This Unikernel is asking for an IPv4 address with DHCP. Luckily a DHCP server is running on the testing nodes. It should assign 192.168.1.100 to it.
In case you enabled ICMP
in the lwip
configuration, you should be able to ping the host from a second terminal.
$ ping 192.168.1.100
For debugging, you can also try to enable Debug messages
in lwip
and increase the debug output with libukdebug
(see Debugging chapter; we need to enabled all debug messages). With this you are able to have a deeper look to the network stack.
If networking is working well, you can use the text-based browser lynx
to see the web page served on a second terminal:
$ lynx 192.168.1.100
- Xen Pages and Wiki
- Documentation
- Mailing list:
- IRC channel
- #unikraft on Freenode
Join us! ;-)