Firecracker MicroVM
Amazon hat auf der AWS re:Invent das Virtualisierungs-Tool Firecracker OpenSource gestellt. Hauptziel bei der Entwicklung war, kleine VMs schnell zu starten die so sicher sind, dass fremder Code darin ausgeführt werden kann. Laut Amazon sind diese beim Serverless Dienst Lambda im Einsatz und dadurch schon millionenfach geprüft. In Zukunft möchte ich versuchen, dass Docker Container automatisch in VMs gestartet werden.
- Firecracker MicroVM Einstieg
- Firecracker VM sicher mit Jailer starten
- Firecracker VM aus Docker Image erstellen
Firecracker versucht dafür mit möglichst wenig Overhead vCPUs, Arbeitsspeicher und ein Dateisystem bereitzustellen. Es können flexibel über eine REST Schnittstelle Festplatten, Netzwerke und Limitierungen gesetzt werden. Aktuell werden nur Intel CPUs unterstützt. Dieses Jahr (2019) sollen AMD und ARM folgen.
Kurz zusammengefasst wird ein Kernel Image, Root Dateisystem und Startargumente gesetzt. In die VM konnte ich mich in unter 2 Sekunden nach Start bereits einloggen.
Firecracker in der Cloud link
Amazon selbst empfiehlt eine EC2 .metal
instance. Ich habe Firecracker bei DigitalOcean mit dem kleinsten Droplet laufen lassen.
Installieren link
Die Firecracker Binary hat keine Software-Abhängigkeiten und kann einfach auf einem x86_64 Linux
heruntergeladen und gestartet werden.
curl -LOJ https://github.com/firecracker-microvm/firecracker/releases/download/v${latest}/firecracker-v${latest}
Im Anschluss kann fürs einfachere Handling die Datei noch umbenannt und die Rechte gesetzt werden:
mv firecracker-v${latest} firecracker
chmod +x firecracker
Erste Schritte link
Für Produktionssysteme sollte Firecracker mit jailer abgesichert werden. Wie das funktioniert werde ich in einem extra Beitrag beschreiben. Eine (hoffentlich) immer aktuelle Installationsanleitung ist im Getting started Artikel zu finden.
Die Firecracker API läuft über einen Socket, der bei Start automatisch angelegt wird. Zur Sicherheit sollte der Pfad vor dem Start einmal gelöscht werden.
rm -f /tmp/firecracker.socket
./firecracker --api-sock /tmp/firecracker.socket
Um eine Firecracker VM zu starten wird ein Linux Kernel und ein ext4
Dateisystem benötigt. AWS stellt hier beides zum ausprobieren zur Verfügung.
curl -fsSL -o hello-vmlinux.bin https://s3.amazonaws.com/spec.ccfc.min/img/hello/kernel/hello-vmlinux.bin
curl -fsSL -o hello-rootfs.ext4 https://s3.amazonaws.com/spec.ccfc.min/img/hello/fsfiles/hello-rootfs.ext4
Anschließend kann in einer neuen Konsole die API genutzt werden. Dabei wird curl
angewiesen die HTTP Requests über den erstellten Socket zu schicken.
Gast Kernel
curl --unix-socket /tmp/firecracker.socket -i \
-X PUT 'http://localhost/boot-source' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"kernel_image_path": "./hello-vmlinux.bin",
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
}'
Gast Rootfs
curl --unix-socket /tmp/firecracker.socket -i \
-X PUT 'http://localhost/drives/rootfs' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"drive_id": "rootfs",
"path_on_host": "./hello-rootfs.ext4",
"is_root_device": true,
"is_read_only": false
}'
Gast Maschine starten
curl --unix-socket /tmp/firecracker.socket -i \
-X PUT 'http://localhost/actions' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"action_type": "InstanceStart"
}'
In der ersten Konsole, in der Firecracker gestartet wurde, fährt nun die VM hoch. Bei Nutzung der AWS hello-rootfs.ext4
kann sich anschließend mit root
und als Passwort root
angemeldet werden. Zum Herunterfahren wird mit reboot
ein Neustart erzwungen, denn die VM nicht durchführt.
In meinen Tests startet die VM mit 1GB Ram bei einer vCPU (DigitalOcean Droplet) in ca 1.1sek.
Ob die virtuelle Maschine läuft kann über den Prozessmanager mit dem Befehl ps aux | grep firecracker
gesehen werden.
VM Limitieren
curl --unix-socket /tmp/firecracker.socket -i \
-X PUT 'http://localhost/machine-config' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"vcpu_count": 2,
"mem_size_mib": 1024
}'
Herunterfahren
Neben einem Neustart innerhalb der VM kann diese auch von außen über die API heruntergefahren werden.
curl --unix-socket /tmp/firecracker.socket -i \
-X PUT "http://localhost/actions" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d "{
\"action_type\": \"SendCtrlAltDel\"
}"
Logs
# Create the required named pipes.
mkfifo logs.fifo
mkfifo metrics.fifo
# Configure the Logger.
curl --unix-socket /tmp/firecracker.socket -i \
-X PUT "http://localhost/logger" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d "{
\"log_fifo\": \"logs.fifo\",
\"metrics_fifo\": \"metrics.fifo\"
}"
CLI firectl link
Die Firecracker firectl ermöglicht über die Firecracker API eine VM zu starten. Der Vorteil gegenüber der direkten API Nutzung besteht darin, das nur ein Command mit vielen Flags genutzt wird anstatt mehreren REST Befehlen.
SDK link
Um programmatisch MicroVMs zu verwalten, gibt es eine Go SDK die auch von firectl verwendet wird.