Unikernel

Estimated reading time: 4 mins

A tweet of Brandon Lum got my attention today. He posted an article about Unikernels which covers a statement from the CTO of IBM about Unikernels about the current situation about Unikernels in the current light of OpenShift (RedHat) and IBM. So, hey it’s the first day of New Year why not start with a little research and some testing around this topic and it’s potential?

What is a Unikernel?

The Idea itself is already some years old and it follows, like the featured picture of this blog post, the idea to capsulate applications even more closer with the operating systems as current container technologies does. Why? As you might already know, containers are always using some kind of base image which is some kind of operating system - like Ubuntu, CentOS, Alpine or whatever. These operating systems are providing the libraries which are needed to run your application inside the container, for example, if you run a PHP application, you will need anything that it needs, an Apache http server, the PHP binaries and of course the share libraries for PHP. In sum, most of the time you need the whole stack. If you are coding Golang applications, you could use a so called scratch containers which is basically a completely empty base image - your binary have to bring everything that it needs to run successfully. But, nevertheless you will still need an operating system, a container runtime and everything else to drive your container.

A Unikernel instead will bundle everything that is needed to drive your application directly with KVM for example - simplified, a Kernel which can be booted by KVM (or something similar), your application and only the needed libraries that your applications needs. Simple, powerful and secure - in theory 😎

The research

I did a research about Unikernels because the article linked above is a little bit thin because it doesn’t provide any information about Unikernels. The wikipedia article about Unikernels does provide some information about projects which are providing Unikernel functionality. After an hour or I found out, that most of the projects are either outdated or are limiting your possibilities.

Pros and Cons

Most of the current Unikernel projects are limiting your possibilities regarding your coding language. You have to imagine, that if you would like to have your Application bundled with an kernel, you have to compile it, whatever this means. The most frameworks are working like serverless functions - they will do the work for you, if you are using the coding language they expect.

Pros

  • Highly secure
  • Can be run directly via the Hypervisor
  • Fast booting
  • Minimal overhead

Cons

  • Hard to debug
  • Complex usage (today)
  • Bad documentation
  • Outdated projects

Demo

But, as always, I would like to test it on my own. Therefore I created a KVM enabled VM on Google Cloud. If you would like to know how to do this, let me know. I decided to go with the Nanos Unikernel which is a commercial project but open sourced the core technologies. They are also providing an OPS project which eases a lot of steps!

Installation

The installation is simple:

$ curl https://ops.city/get.sh -sSfL | sh

Install Golang for Ubuntu:

sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt-get update
sudo apt-get install golang-go

Create a simple go program - the example is taken from the NanoVMs homepage - if you like you can follow it there too:

First create a server.go:

  package main

  import (
      "log"
      "net/http"
  )

  func main() {
      fs := http.FileServer(http.Dir("static"))
      http.Handle("/", fs)

      log.Println("Listening...on 8080")
      http.ListenAndServe(":8080", nil)
  }

Compile the binary:

$ GOOS=linux go build server.go

Create a file structure:

  $ mkdir static
  $ cd static

Create the hello.html:

  <!doctype html>
  <html>
  <head>
  <meta charset="utf-8">
      <title>A static page</title>
  </head>
  <body>
      <h1>Hello from a static page</h1>
  </body>
  </html>

Create a config file config.json for ops:

  {
      "Dirs" : ["static"],
      "Files":["/lib/x86_64-linux-gnu/libnss_dns.so.2", "/etc/ssl/certs/ca-certificates.crt"]
  }

Build an run the KVM image:

ops run -p 8080 -c config.json server

Check the output

First lookup if the created page is served:

Second, have a look at the process runtime. There you can see, that we are really running an KVM image including our binary.

Third, if you configured the Google Cloud Platform firewall correctly, you can lookup the page via a browser:

Conclusion

This can be a really nice technology in the future. I will do a analysis about the content of the KVM image because I would like to know whats inside of it. Therefore, stay tuned. In summery, this is a very neat way to run services with a minimum footprint in a very secure manner!

Mario

Posted on: Wed, 01 Jan 2020 00:00:00 UTC by Mario Kleinsasser
  • Container
  • Unikernel
  • Doing Linux since 2000 and containers since 2009. Like to hack new and interesting stuff. Containers, Python, DevOps, automation and so on. Interested in science and I like to read (if I found the time). My motto is "𝗜𝗺𝗮𝗴𝗶𝗻𝗮𝘁𝗶𝗼𝗻 𝗶𝘀 𝗺𝗼𝗿𝗲 𝗶𝗺𝗽𝗼𝗿𝘁𝗮𝗻𝘁 𝘁𝗵𝗮𝗻 𝗸𝗻𝗼𝘄𝗹𝗲𝗱𝗴𝗲. [Einstein]". Interesting contacts are always welcome - nice to meet you out there - if you like, do not hesitate and contact me!