Running Unikernels in 2019 with OPS

By | February 25, 2019

Unikernels have spent far too long as an academic exercise as researchers tried to figure out ways of shrinking the operating system while improving application security and performance. One of the largest problems with unikernels has traditionally been that they have remained out of reach for the average developer because of their reliance on low-level coding requiring specialized knowledge that a lot of web developers simply never needed to learn.

But wait – what is a unikernel anways?

A unikernel is a specialized virtual machine that is the synthesis of the application and the operating system together. It includes only what a single application needs in order to run.

Typically for a web application, that means it needs to talk to the disk, the network and include a clock. It doesn’t need things like USB support or floppy disk drivers or 30 different ethernet adapters – stuff you’ll find in every single stock Linux distribution out there.

Did you know that the Linux kernel is now north of 15M lines of code and contains nearly 400 system calls? All of this growth has been happening for 30 years now and it really has not changed much from UNIX that was made in the late 1960s. Things need to change. Mounting security problems, cloud cost, and performance issues are holding all of us back.

Enter [OPS](https://github.com/nanovms/ops) is a new free open source tool designed to easily build and orchestrate unikernels from raw Linux binaries. What does this mean? It means you can now build and run unikernels locally on your own laptop or in the cloud without having to fiddle around with Make.

You don’t have to install 3rd party libc replacements. You don’t need to go patching MySQL guts. Why would you do that? OPS is written for the practicing DevOps engineer or the software engineer that just wants to get stuff done.

Ok – enough of this – let’s dive in.

First things first – go to https://ops.city and download ops. You can do this via:

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

However, if you’re the type that is distrusting of installs like that you can always install from source as well found at https://github.com/nanovms/ops.

After you install let’s try a simple node application. Put this into hi.js:

console.log("hello from inside a unikernel!");
‘ops list’ you’ll see this output which has a growing list of packages you can use

If you run ‘ops list’ you’ll see this output which has a growing list of packages you can use. We can run this one by downloading the node package.

Build Your Own Unikernel

Wow – you’ve just built and ran your own unikernel – it’s kinda like building your own little single-purpose operating system – cause that’s all that is actually running inside of it. There is no init manager. There is no snap daemon.

 

There is nothing else fighting your processor for precious resources and more importantly no way for an attacker to fork a shell and do something nefarious like installing a crypto miner on it.

It’s important to note that while we ran an existing package in OPS here you can actually load raw arbitrary Linux binaries as well. Want to see something cool?

Stick this into a new main.go:

package main
import 
(
      "fmt"
      "net/http"
)

func main() 
{
      http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) 
      {
            fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
      }
      http.ListenAndServe(":8080", nil)
}

Go ahead and build it for a Linux target via:

GOOS=linux go build

Now – I’m writing this on a mac mind you but after building this we can tell OPS to run it and set a port for the server to listen on. OPS wraps itself around qemu and we by default will run in user mode.

Now if we hit it up with curl we can see that it works just fine.

OPS Curl Statement

Last thing I want to show you before I leave.

➜  gt  ls -lh gt

-rwxr-xr-x  1 eyberg  staff   6.2M Feb 20 16:26 gt

➜  gt  ls -lh ~/.ops/images/gt.img

-rw-r--r--  1 eyberg  staff   8.3M Feb 20 16:28 /Users/eyberg/.ops/images/gt.img

The first line is the Go binary we built weighing in at 6.2M. The next one? Yeh – that’s the disk image we orchestrate in qemu weighing in at a whopping 8.3M. That’s not just the app. That’s not just the operating system. That’s everything to boot.

 

So go to https://github.com/nanovms/ops – star it, fork it, download it and let me know what you build with it!

Let's Discuss