Are NanoVMs the future?

This brilliant take-down of the containers ecosystem made quite a splash yesterday, with the predicably heated discussion on HN.

The author's key point was that containers are ihnerently difficult - if not impossible - to secure - and that we need new approach, one that is breaking from the outdated concept of multi-user, multi-process operating systems we have today that do not belong in the cloud.

This reply from the commenter "api" summarizes the situation:

I've been saying for years that containers are nothing more than an ugly hack to get around the fact that OSes are broken. More specifically modern OSes still carry 1980s assumptions about multi-tenancy, system administration, application management, state management, etc.

In the 1980s a "server" was a big expensive special snowflake. Each server had a "system administrator." The system administrator would "install" software "on" the machine.

I quoted all those words to highlight no longer valid concepts.

Boxes are ephemeral now. Systems have more than one administrator, sometimes belonging to a different organization or department. Applications are not installed "on" the system in the sense that they root into it and modify its state. If they do this makes them a terrible hassle to manage. Applications should be ephemeral things that can float freely between machines and store their state in some kind of distributed or remote data store or database, or at least can be easily migrated between hosts. Everything is mobile. Everything is commodity. Everything is liquid.

OSes are just not designed this way, so we have an ugly hack called a container that basically amounts to "let's tar up images of operating systems and just treat them like giant static binaries." Onto this is bolted a whole array of other ugly hacks to make that easy to deal with, but the concept is fundamentally ugly as hell.

I'll admit my expertise in information security isn't solid enough to evaluate the argument on its technical merits. During development, containers are a God-send in that I can quickly spin-up dependencies without going through a lengthy install-and-configure process. In production, I'll take whatever approach offers the best security given the requirements.

The author is a CEO at NanoVMs, and he claims that the answer are unikernels and micro/nano VMs where your application is the only thing that's running.

I don't have a problem with the obvious bias his role brings to his argument; I'll take a report from the trenches with a lot more seriousness than one from an Ivory Tower journalist.

Interested, I looked around to see if I can try this tech at home for personal education.

First steps with Nanos

From the README

Nanos is a new kernel designed to run one and only one application in a virtualized environment. It has several constraints on it compared to a general purpose operating system such as Windows or Linux - namely it's a single process system with no support for running multiple programs nor does it have the concept of users or remote administration via ssh.

I am not going to be hacking on Nanos but instead use it for a toy project and see if I can get it running locally.

To that end, README tells me to use the Ops orchestrator to run my application.

There, I open the Getting Started guide and find out that Ops currently supports only *nix systems. Does my WSL2 count as one? I'll find out.

First, I install qemu:

sudo apt-get install qemu

Next, I trust Ops to do the right thing and install it from the web:

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

It downloads and install into my user's directory. I source the .bashrc file to put its install location into my $PATH.

Time to run the first app! I copy-and-paste the example from the homepage:

var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8083, "0.0.0.0");
console.log('Server running at http://127.0.0.1:8083/');

Then I try running it:

ops load node_v12.13.0 -p 8083 -f -n -a hi.js

Oops:

booting /home/tomas/.ops/images/node.img ...
qemu-system-x86_64: warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
assigned: 10.0.2.15
buffer.js:573
slice: (buf, start, end) => buf.utf8Slice(start, end),
^

RangeError: Index out of range
at Object.slice (buffer.js:573:37)
at Buffer.toString (buffer.js:770:14)
at Object.readFileSync (fs.js:386:41)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:972:22)
at Module.load (internal/modules/cjs/loader.js:812:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
at internal/main/run_main_module.js:17:11 {
code: '
ERR_OUT_OF_RANGE'
}
exit status 3

Not going to debug this now, I look up what other versions of Node are supported on Nanos via ops pkg list and try 11.5.0.

booting /home/tomas/.ops/images/node.img ...
qemu-system-x86_64: warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
assigned: 10.0.2.15
Server running at http://127.0.0.1:8083/

I navigate to localhost:8083, and indeed, "Hello World" it says in my browser. Neat!

WSL is a marvel. I can experiment with tech that is Linux-only without having to dual-boot or fight with Virtualbox. I will now try to run a more sophisticated app on Nanos and report back what I find.