Unikernels have drifted in and out of devops conversations about what is coming down the pipeline, however, for the majority of developers they have been in-accessible due to their complexity and their low level nature. Most implementations are written in esoteric languages or involve lots of low level c programming - just simply not something that your average developer is going to be exposed to.
Real quick - you can think of a unikernel as a way of deploying your application as it's own little operating system. Unlike Linux that is a general purpose operating system a unikernel is specially designed to run only one program - yours. Engineers find this interesting because it means you can run your code faster, more secure and since they are roughly the size of your application you can run a lot of them. Some people think of them as containers++ or containers 2.0, although personally I don't think they are anything like containers but that's just me.
OPS is a project designed to fix the problems of allowing everyone to build and run unikernels. It is specifically designed to have a focus on ease of use while at the same time embracing unikernel concepts. OPS allows anyone - including those that don't code to build and run linux programs as unikernels.
Want to get started? Ok.
The first thing you want to do is install OPS. You can download the binary like this or goto the source .
curl https://ops.city/get.sh -sSfL | sh
From there let's try a php example.
If we plop this into example.php
<?php
phpinfo();
?>
We can run it like this:
$ ops load php_7.2.13 -a example.php
What this will do is download a base package that has a nice install of php bundled up ready to go. If you are feeling adventurous you can even create these packages yourself but to get started will just use a pre-made one.
What this does is load your example.php onto a filesystem that it creates on the fly along with everything php wants/needs to run it. Then it spins up qemu to run it as a virtual machine.
What we are doing here is basically mimicking what happens in the cloud providers like GCE and AWS. In fact they use private forks of KVM to power their clouds. It's important to note that in this example we are not using KVM and we are in what's called 'usermode' networking. It's definitely slower but you can also enable KVM acceleration by running this on linux or installing Intel HAX.
Want to try a larger example? How about a go web server?
Put this into a main.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)
}
Now let's build it like we are going to deploy it to a linux server. It's important to note that OPS doesn't actually run linux - it runs linux binaries. It can do this because it speaks the POSIX standard (loosely). However, there are definitely certain things that linux does that it will never do and that's by design.
$ GOOS=linux go build main.go
Once we have it built we can go ahead and create a static folder with a index.html in it:
mkdir static
cd static
Throw this in to index.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>
Now we are going to show some of the config.json functionality:
{
"Dirs" : ["static"]
}
In this example what we've told OPS is to stuff the static directory onto it's filesystem as it is building the virtual machine image. Keep in mind we are converting your program into a 'virtual machine' - so that's the same thing as an AWS AMI or GCE image. (In fact you'll see that as a deploy option in the near future.)
From there you can build && run it:
$ ops run -p 8080 -c config.json server
What this does is open up port 8080 and run the app. Now you should be able to hit the webserver:
curl http://localhost:8080/hello.html
You just built your own bootable operating system which only has your application inside of it.
Want to see something even cooler?
If you compare the 'image' filename to the 'main' binary you see the difference? You've got a VM clocking in at just over 8M which is still roughly the size of your go webserver.
ls -lh
total 29752
-rw-r--r-- 1 eyberg staff 8.2M Jan 22 14:50 image
-rwxr-xr-x 1 eyberg staff 6.3M Jan 22 14:50 main
-rw-r--r-- 1 eyberg staff 198B Jan 22 13:27 main.go
OPS has a lot more functionality in it than what we exposed in this article and the ecosystem is growing by the day with more packages and better support.
It's worth your time investigating unikernels. The big cloud providers have made it pretty clear that they are prepping for massive adoption of these types of systems with gVisor from Google and Firecracker from AWS. While these are not unikernels per-se they are very heavy indications of what is coming down the pipeline.
I'm personally very excited about the new forms of compute that unikernels open up because of their size, performance, and security implications. I think they'll play a bit part in serverless runtimes, edge compute and many other interesting ecosystems.