Posted at

AWS Firecrackerを触ってみる


Firecrackerとは

AWS re:invent 2018で発表された新サービス?というかOSSです。

Firecrackerの紹介

概要を見たときは前にまとめたKata Conteinersに似ていると思いましたがFirecrackerはVMMみたいなので完全に別物ですね。

そういう認識があるのかGithub上にもKataContainersとの違いが書いてあったりします。

Firecracker Github

What is the difference between Firecracker and Kata Containers and QEMU?


  • FirecrackerはVMM

  • KVMベースでQEMUの代わりに動作するプロセス

  • LambdaやFargate用基盤で使われているらしい

image.png

Firecracker のデザインについて調べてみた


  • Firecracker はユーザー空間で動作する

  • Linuxカーネルベースの仮想マシン(KVM)を使用して microVM を作成する

  • Firecracker は QEMU に代わる幅広い機能を備えた VMM(仮想マシンモニター)

  • 様々なゲストOS をホストする

  • Firecracker プロセスはvCPUの数の設定やマシンの起動などの一般的な操作を RESTful API 経由で制御できる

  • Firecracker プロセスは同じマシン上の何千ものマイクロVMによって使用されるネットワークとストレージのリソースを細かく制御できるように、レートリミッタを内蔵している

  • Firecracker はホストとゲストOS 間で構成情報を安全に共有するメタデータサービスも提供する

  • Firecracker API を使用してメタデータサービス構成および設定ができる

RESTful APIで制御可能な、最適化されたVMMであるというところが魅力ですね。


触ってみる

まあ、Githubのインストールページを参考にしているだけですが。

FirecrackerはAWSだとベアメタルインスタンス(i3.metal)で実行する必要がありそうです。

今回はGCEのネストインスタンスを使ってみます。

ネストインスタンスとは入れ子の意味でVM内で更にVMを動かす時の仕組みです。

Google Compute Engine、仮想マシンの入れ子(Nested Virtualization)を可能に。KVM対応


事前準備


OS



  • Linux 4.14+


    • Firecracker currently supports physical Linux x86_64 hosts, with kernel version 4.14 or later.

    • KVM



  • you have KVM enabled in your Linux kernel


  • you have read/write access to /dev/kvm



Docker Install

$ sudo apt-get update

$ sudo apt-get install docker.io

$ sudo yum install docker
$ sudo systemctl start docker
$ sudo usermod -aG docker $USER


ダウンロード

モジュールをダウンロードすればそのまま使えます。

ソースコードを自分でビルドもできます。

$ curl -fsSL -o firecracker  https://github.com/firecracker-microvm/firecracker/releases/download/v0.11.0/firecracker-v0.11.0

$ chmod +x firecracker
$ ls -l
total 6008
-rwxr-xr-x 1 root root 6151112 Nov 29 13:40 firecracker

$ ./firecracker -V
firecracker 0.11.0


プロセス実行

$ rm -f /tmp/firecracker.sock

$ firecracker --api-sock /tmp/firecracker.sock

これを実行するとフォアグラウンドでターミナルを占有してしまうので別ターミナルでアクセスします。

ここで作ったunix domain socketに対してRESTful APIでアクセスできます。

/をGETすると応答があります。

$ sudo curl --unix-socket /tmp/firecracker.sock -i http://localhost/

HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 29 Nov 2018 09:53:21 GMT

{"id":"anonymous-instance","state":"Uninitialized"}


テストVM実行

AWS公式のS3上にテストイメージがあるのでダウンロードします。

$ 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
$ ls -l
total 57496
-rwxr-xr-x 1 root root 6151112 Nov 29 13:40 firecracker
-rw-r--r-- 1 root root 31457280 Nov 29 13:56 hello-rootfs.ext4
-rw-r--r-- 1 root root 21266136 Nov 29 13:54 hello-vmlinux.bin


バイナリアップロード

$ curl --unix-socket /tmp/firecracker.sock -i \

-X PUT 'http://localhost/boot-source' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"kernel_image_path": "/usr/firecracker/hello-vmlinux.bin",
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
}'

HTTP/1.1 204 No Content
Date: Thu, 29 Nov 2018 13:58:52 GMT


rootファイルシステムアップロード

$ curl --unix-socket /tmp/firecracker.sock -i \

-X PUT 'http://localhost/drives/rootfs' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"drive_id": "rootfs",
"path_on_host": "/usr/firecracker/hello-rootfs.ext4",
"is_root_device": true,
"is_read_only": false
}'

HTTP/1.1 204 No Content
Date: Thu, 29 Nov 2018 14:00:13 GMT

なんとなーくlsofで見てみると/dev/kvmやら関連ファイルが開かれています。

$ lsof /tmp/firecracker.sock

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
firecrack 21848 root 8u unix 0xffffa0553bca6000 0t0 84467 /tmp/firecracker.sock type=STREAM

$ lsof -p 21848

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
firecrack 21848 root cwd DIR 8,1 4096 2 /
firecrack 21848 root rtd DIR 8,1 4096 2 /
firecrack 21848 root txt REG 8,1 6151112 519615 /usr/firecracker/firecracker
firecrack 21848 root 0u CHR 136,0 0t0 3 /dev/pts/0
firecrack 21848 root 1u CHR 136,0 0t0 3 /dev/pts/0
firecrack 21848 root 2u CHR 136,0 0t0 3 /dev/pts/0
firecrack 21848 root 3u a_inode 0,13 0 10602 [eventfd]
firecrack 21848 root 4u a_inode 0,13 0 10602 [eventfd]
firecrack 21848 root 5u a_inode 0,13 0 10602 [eventpoll]
firecrack 21848 root 6r FIFO 0,12 0t0 84466 pipe
firecrack 21848 root 7w FIFO 0,12 0t0 84466 pipe
firecrack 21848 root 8u unix 0xffffa0553bca6000 0t0 84467 /tmp/firecracker.sock type=STREAM
firecrack 21848 root 9u a_inode 0,13 0 10602 [eventpoll]
firecrack 21848 root 10u a_inode 0,13 0 10602 [timerfd]
firecrack 21848 root 11u CHR 10,232 0t0 384 /dev/kvm
firecrack 21848 root 12u a_inode 0,13 0 10602 kvm-vm
firecrack 21848 root 13u a_inode 0,13 0 10602 [eventfd]
firecrack 21848 root 14u a_inode 0,13 0 10602 [eventfd]
firecrack 21848 root 15u a_inode 0,13 0 10602 [eventfd]
firecrack 21848 root 16u a_inode 0,13 0 10602 [eventfd]
firecrack 21848 root 18r REG 8,1 21266136 519617 /usr/firecracker/hello-vmlinux.bin


VM起動

$ curl --unix-socket /tmp/firecracker.sock -i \

-X PUT 'http://localhost/actions' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"action_type": "InstanceStart"
}'

HTTP/1.1 204 No Content
Date: Thu, 29 Nov 2018 14:09:20 GMT

VMを起動させるとfirecrackerプロセスを実行したターミナル側にバーッと起動メッセージが出力され、その後にカーネルが起動してきます。

[    0.000000] Linux version 4.14.55-84.37.amzn2.x86_64 (mockbuild@ip-10-0-1-79) (gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)) #1 SMP Wed Jul 25 18:47:15 UTC 2018

[ 0.000000] Command line: console=ttyS0 reboot=k panic=1 pci=off root=/dev/vda virtio_mmio.device=4K@0xd0000000:5
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[ 0.000000] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256
[ 0.000000] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format.
[ 0.000000] e820: BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x0000000007ffffff] usable
[ 0.000000] NX (Execute Disable) protection: active
[ 0.000000] DMI not present or invalid.
[ 0.000000] Hypervisor detected: KVM



<中略>

2018-11-29T14:09:22.416078504 [:WARN:vmm/src/lib.rs:903] Guest-boot-time = 1490307 us 1490 ms, 1485027 CPU us 1485 CPU ms
OpenRC init version 0.35.5.87b1ff59c1 starting
Starting sysinit runlevel

OpenRC 0.35.5.87b1ff59c1 is starting up Linux 4.14.55-84.37.amzn2.x86_64 (x86_64)



<中略>

Welcome to Alpine Linux 3.8
Kernel 4.14.55-84.37.amzn2.x86_64 on an x86_64 (ttyS0)

localhost

最後にログインプロンプトが表示されます。

VM起動しました。

ここでステータスを見てみるとstateがRunningになっています。

$ curl --unix-socket /tmp/firecracker.sock -i http://localhost/

HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 29 Nov 2018 14:17:03 GMT

{"id":"anonymous-instance","state":"Running"}

他にもfirecrackerのAPIがあるんでGET系のものを実行してみます。

$ curl --unix-socket /tmp/firecracker.sock http://localhost/machine-config

{ "vcpu_count": 1, "mem_size_mib": 128, "ht_enabled": false, "cpu_template": "Uninitialized" }


VMにログイン

このVMイメージの場合はrootアカウントにrootパスワードでログインできます。

localhost login: root

Password:
Welcome to Alpine!

The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org>.

You can setup the system with the command: setup-alpine

You may change this message by editing /etc/motd.

login[984]: root login on 'ttyS0'
localhost:~#

とりあえずVMMとしてVM起動まで~

まあ、これだけだとQEMUとの違いとかがわからないっすね