Go to file
Hannes Mehnert 9696953cd7 revise force-restart: now with wait for kill and resource cleanup before start
allows to cleanup various hacks, such as checking for pid in vmm_resources
or removing temporarily the allocated resources from the resource map in vmm_engine

semantics is now slightly different, but for sure enhanced.
- each VM has a Lwt.wait () task attached in Vmm_engine.t (tasks : 'c String.Map.t)
- normal create shouldn't be much different, apart from memoizing the sleeper
- after waitpid is done in vmmd, and vmm_engine.shutdown succeeded, Lwt.wakeup is called for the sleeper
- force create now:
 - checks static policies
 - looks for existing VM (and task), if present: kill and wait for task in vmmd
 - continue with presence checking of vm name, dynamic policies, allocate resources (tap, img, fifo)

this means the whole randomness in filenames can be removed, and the
communication between vmm_console and vmm_client is working again (attach/detach
could not work since vmm_console knew only about "albatross.AAA.BBB.RANDOM",
whereas vmm_client insisted on "AAA.BBB"

resource overcommitment (and races in e.g. block device closing + opening) are
gone now, only if the old vm is cleanup up, resources for the new one are
allocated and it is executed
2018-04-05 01:02:45 +02:00
app revise force-restart: now with wait for kill and resource cleanup before start 2018-04-05 01:02:45 +02:00
pkg vmm_stats: fix fd leaks (fixes #10) 2018-03-24 22:33:51 +01:00
provision style 2018-03-22 17:00:08 +01:00
src revise force-restart: now with wait for kill and resource cleanup before start 2018-04-05 01:02:45 +02:00
stats Vmm_core.cmd is now a variant (no longer polymorphic variant), some renames in Vmm_wire.Stats and Vmm_wire.Console to disambiguate 2018-04-04 22:16:31 +02:00
.gitignore initial 2017-07-10 10:38:25 +01:00
.merlin compression, fixes #6 2018-03-22 17:00:08 +01:00
.travis.yml no need to run tests via travis, they don't exist (yet) 2018-03-23 17:04:35 +01:00
_tags style: require lwt 3.0.0, fix warnings, disable 4 (fragile pattern matching) and 48 (implicit elimination of optional argument) 2018-04-03 22:58:31 +02:00
CHANGES.md initial 2017-07-10 10:38:25 +01:00
LICENSE.md initial 2017-07-10 10:38:25 +01:00
myocamlbuild.ml vmmd: 2017-09-14 21:47:07 +01:00
opam style: require lwt 3.0.0, fix warnings, disable 4 (fragile pattern matching) and 48 (implicit elimination of optional argument) 2018-04-03 22:58:31 +02:00
README.md [ci skip] add travis badge 2018-03-22 17:00:08 +01:00

Albatross: Managing virtual machines

Build Status

A set of binaries to manage, provision, and deploy virtual machine images. This is very much work in progress, don't expect anything stable.

Please read the blog article for motivation and an overview.

The implementation uses explicit errors (no exceptions), and make mostly use of the (blocking!) Bos library for operating system commands. A thin layer of Lwt is used on top to (more gracefully) handle multiple connection, and to have a watching thread (in waitpid(2)) for every virtual machine started by vmmd.

To install Albatross, run opam pin add albatross https://github.com/hannesm/albatross. On FreeBSD, opam pin add solo5-kernel-ukvm --dev is needed as well.

The following elaborates on how to get the software up and running, following by provisioning and deploying some unikernels. There is a server (SRV) component which needs six binaries: vmm_console, vmm_log, vmm_stats_lwt, vmmd, ukvm-bin.none, and ukvm-bin.net; a CA machine (which should be air-gapped, or at least use some hardware token) for provisioning which needs vmm_sign, and vmm_gen_ca; and a development (DEV) machine which has a fully featured OCaml and MirageOS environment. Each step is prefixed with the machine it is supposed to be executed on. Of course you can conflate everything into a single development system or your server, all up to you and your security scenario.

Exact file transfer operations between these machines is not in scope of this document, but kept abstract as COPY. Some commands require superuser privileges (use sudo, su, or doas), I prefixed them with #.

File endings used in this document:

  • .db for CA databases
  • .pem for (PEM-encoded) signed certificates
  • .key for (PEM-encoded) private keys
  • .req for (PEM-encoded) certificate signing requests

Setup a certificate authority

The first step is to setup a certificate authority (private key and CA certificate). The CA private key can sign and revoke everything, you should better keep it in a safe place (air-gapped machine etc.) - not on the server!

CA> vmm_gen_ca ca ca.db [--days 3650] [--server "server"] [--server-days 365]

This generated five files:

  • ca.key which is the CA private key
  • cacert.pem which is the CA certificate
  • ca.db which contains a map between serial number and name of issued certificates
  • server.pem is the server certificate
  • server.key is the private key of the server

Server setup

If you have installed this package on your development machine, follow some more steps to produce the remaining required binaries:

CA> COPY cacert.pem server.pem server.key SRV:
DEV> git clone https://github.com/mirage/mirage-skeleton.git
DEV> cd mirage-skeleton/tutorial/hello
DEV> mirage configure -t ukvm
DEV> mirage build
DEV> mv ukvm-bin /tmp/ukvm-bin.none
DEV> cd ../device-usage/network
DEV> mirage configure -t ukvm
DEV> mirage build
DEV> mv ukvm-bin /tmp/ukvm-bin.net
DEV> cd ../../..
DEV> COPY /tmp/ukvm-bin.none /tmp/ukvm-bin.net SRV:
DEV> COPY vmm_console vmm_log vmm_stats_lwt vmmd SRV:
SRV> vmm_console -vv cons.sock &
SRV> vmm_log -vv log.out log.sock &
SRV> vmm_stats_lwt -vv stat.sock & #optional
SRV# vmmd -vv . cacert.pem server.pem server.key

Some setup for network interfaces is needed, depending on your operating system. You can also add NAT to allow your virtual machines to talk to the outside world, or add your external interface to the bridge directly, or just keep your VMs local.

# FreeBSD
SRV# ifconfig bridge create #should output bridge0
SRV# ifconfig bridge0 name ext
SRV# sysctl net.link.tap.up_on_open=1
# Linux
SRV# brctl addbr ext

Provision our first virtual machine

We will delegate some resource to a certificate and key we keep on our development machine.

DEV> vmm_req_delegation dev 2 1024 --cpu 1 --bridge ext/10.0.0.2/10.0.0.5/10.0.0.1/24
DEV> COPY dev.req CA:

This produced two files, dev.req and dev.key. Keep the key in a safe place!

CA> vmm_sign ca.db cacert.pem ca.key dev.req [--days 10]
CA> COPY dev.pem DEV:

Now, our DEV machine can use its delegation certificate for issuing other certificates. We'll create a certificate for interactive use, and one containing the hello unikernel.

DEV> vmm_req_permissions admin --permission all
DEV> vmm_sign dev.db dev.pem dev.key admin.req

This produced in the first step two files, admin.req and admin.key, and in the second step two more files, dev.db and admin.pem.

DEV> vmm_req_vm hello mirage-skeleton/tutorial/hello/hello.ukvm 12 1
DEV> vmm_sign dev.db dev.pem dev.key hello.req

This generates a private key hello.key and a certificate signing request named hello.req including the virtual machine image hello.ukvm, which gets 12MB memory and CPU id 1. The second command used the dev.key to sign the signing request and output a hello.pem.

The flag --force can be passed to vmm_req_vm. This means: if there already exists a running virtual machine with the same name, kill it and start the new one provided in the certificate.

To actually deploy anything, the server needs the chain (i.e. the vm certificate and the delegation certificate). Our client needs the main CA certificate to authenticate the server itself.

CA> COPY cacert.pem DEV:
DEV> cat admin.pem dev.pem > admin.bundle
DEV> cat hello.pem dev.pem > hello.bundle

And deploying (watch the output of the processes started on the server above!):

DEV> vmm_client cacert.pem hello.bundle hello.key SRV:1025
DEV> vmm_client cacert.pem admin.bundle admin.key SRV:1025 --db dev.db

Commands are at the moment info, statistics, destroy, attach, detach, and log.