Running the Nanos Unikernel Inside Firecracker
Running the Nanos Unikernel Inside Firecracker
In this article, learn how to run the Nanos Unikernel inside Firecracker.
Join the DZone community and get the full member experience.Join For Free
A lot of people seem to be under the impression that Firecracker is a competing technology against unikernels. It actually isn't. It's more of an alternative to existing machine monitors such as qemu and is actually complementary if you need the quick boot times. As for isolation levels you are going to have about the same isolation as you would get with KVM - it uses the same facilities underneath.
There is another very common misconception that firecracker somehow makes your application go faster at runtime. This is, at least today, definitely not the case as discussed in this issue. If anything you will notice your application slows down considerably. What is faster is the boot time. The boot time, if you are concerned about such a thing, does indeed become much faster, although again, take this with a few caveats. If you are sticking something like the JVM or rails inside firecracker your boot time arguments get effectively thrown away because they are already incredibly slow to boot. I suppose comparing with a linux instance you would shave off some but comparing with a unikernel not so much. This isn't necessarily a bad thing.
As indicated in some of the linked mailing list comments there seem to be plans on fixing the runtime performance, however, you should be aware of what you are getting into.
Ok, enough disclaimers - let's get with the code.
Install Firecracker and Nanos
Before you try anything out be aware that none of this will work without having access to hardware acceleration. So if you are in the cloud that means nested virtualization on GCloud or metal instances on AWS otherwise stick to bare metal.
A quick way to check is to grep your cpuinfo:
There's a handful of other cpu flags that aren't documented that you'll need but suffice to say just make sure your server was built in the past 5-6 years and you'll probably be good. You might be asking how OPS and Nanos can deploy to the cloud without relying on special instance types. The reason is OPS deploys raw unikernels straight to the cloud. Not having an underlying linux means you get access to the raw virtualization inherently present, not to mention you won't have to deal with orchestration.
Ok, first things first, let's install firecracker:
Now let's install ops:
For the purposes of this article we'll only be using ops to build our unikernel - not run it. We'll leave the running to firecracker.
If you wish to run the unikernel in firecracker you can use this vm_config.json template below.
As you will note I've pointed the kernel_image_path to the stage3 from Nanos found in ~/.ops/0.1.26/stage3.img and I've pointed the image to whatever image you've built with ops. In this case it is located in ~/.ops/images/my_img.img. Other than that everything is fairly vanilla.
Next you'll want to install a DHCP server - cause without it you really can't do anything. Keep in mind the only way to talk to a unikernel is over the network and there is no way to login to these. Also, using firecracker kind of implies that you'll probably have multi-tenants to begin with.
You can setup the dhcp server with this config like so:
(Found in /etc/dhcp/dhcpd.conf):
Create a tap device for your dhcp server to listen in on:
Run it against your tap device. You'll want this running before running firecracker.
You should see some ARP requests fly by once firecracker boots:
Once you boot your unikernel you should also see it grab an ip:
I've found it easier to play with firecracker by breaking up the one large default vm_config.json into multiple commands each with different configs. I've also set up logging cause frankly it's a pain to understand what is going on without it.
This sets up the entry point for firecracker. Each socket needs to be unique so once you are done with it don't forget to remove it if you wish to re-use it later on. For this initial boot we simply point it at stage3 found in the latest ops release we have:
This one points firecracker at our root fs that gets loaded. This is the actual image that you are building with ops. We treat this differently than ops does as we bypass a bunch of booting setup that we'd normally have to do using something like KVM.
This sets the machine parameters for our firecracker instance. Nothing special here.
Next we start the instance:
Then we'll create 2 pipes and attach the logs to them. Note: You most definitely should do this. I'm not quite sure why this is so obtuse or why the documentation for this was hidden inside of a github ticket. The logs are invaluable to understand what is going on in firecracker when things "just don't work".
To read your logs you'll need this little script:
Then to actually read the logs:
Opinions expressed by DZone contributors are their own.