katacontainers
Firecracker

Firecracker + Kata を動かしてみるところまで

KataでFirecrackerをサポートしたようです。

セキュアなコンテナランタイム「Kata Container」が、AWSのマイクロVM「Firecracker」をサポート

たまたまKata ContainerもFirecrackerも触った事があるので

せっかくなんで動かしてみます。

qemuの代わりにFirecrackerでVMを起動するようにKataを設定する、という感じですね。


やってみる

とりあえずKata ContainerのGithubページへ。

image.png

More Users GuideHOWTO: Kata Containers with Firecrackerが追加されていますね。

https://github.com/kata-containers/documentation/wiki/Initial-release-of-Kata-Containers-with-Firecracker-support

今回はDockerを使いますがドライバの関係でバージョンが18.06じゃないとダメみたいです。


$ sudo dpkg -l | grep docker
ii docker-ce 18.06.2~ce~3-0~ubuntu amd64 Docker: the open-source application container engine

Kataをダウンロードして展開。


$ wget https://github.com/kata-containers/runtime/releases/download/1.5.0/kata-static-1.5.0-x86_64.tar.xz

$ tar -xvf kata-static-1.5.0-x86_64.tar.xz -C /

deamon.jsonを作ってRuntime設定を追加。


/etc/docker/daemon.json

{

"runtimes": {
"kata-fc": {
"path": "/opt/kata/bin/kata-fc"
},
"kata-qemu": {
"path": "/opt/kata/bin/kata-qemu"
}
},
"storage-driver": "devicemapper"
}

リロード。


$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

DockerのRuntime設定にkata-fcとkata-qemuが追加されています。

Qemuで動かしたい時はkata-qemuを使えばいいみたいです。


$ docker info | grep "Runtimes"
Runtimes: kata-fc kata-qemu runc

vsockモジュールをロードします。

$ modprobe vhost_vsock

実行前にkvmを使っているディスクリプタをチェック。

特になし。


$ sudo lsof | grep kvm

docker run時にrutimeでkata-fcを指定します。


$ sudo docker run --runtime=kata-fc -itd --name=oh-sweet-fc alpine sh
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2723b5c68c0 alpine "sh" 37 minutes ago Up 37 minutes oh-sweet-fc

firecrackerが実行されているみたいです。


$ ps -ae | grep -E "kata|fire"
27134 ? 00:00:08 firecracker
27147 pts/0 00:00:00 kata-shim

ファイルディスクリプタを見てみるとFirecrackerが/dev/kvmへアクセスしていますねー


$ sudo lsof | grep kvm
firecrack 27134 root mem REG 0,13 10612 anon_inode:kvm-vcpu (stat: No such file or directory)
firecrack 27134 root 12u CHR 10,232 0t0 384 /dev/kvm
firecrack 27134 root 13u a_inode 0,13 0 10612 kvm-vm
firecrack 27134 root 88u a_inode 0,13 0 10612 kvm-vcpu
fc_vmm 27134 27135 root mem REG 0,13 10612 anon_inode:kvm-vcpu (stat: No such file or directory)
fc_vmm 27134 27135 root 12u CHR 10,232 0t0 384 /dev/kvm
fc_vmm 27134 27135 root 13u a_inode 0,13 0 10612 kvm-vm
fc_vmm 27134 27135 root 88u a_inode 0,13 0 10612 kvm-vcpu
fc_vcpu0 27134 27139 root mem REG 0,13 10612 anon_inode:kvm-vcpu (stat: No such file or directory)
fc_vcpu0 27134 27139 root 12u CHR 10,232 0t0 384 /dev/kvm
fc_vcpu0 27134 27139 root 13u a_inode 0,13 0 10612 kvm-vm
fc_vcpu0 27134 27139 root 88u a_inode 0,13 0 10612 kvm-vcpu
kvm-pit/2 27138 root cwd DIR 8,1 4096 2 /
kvm-pit/2 27138 root rtd DIR 8,1 4096 2 /
kvm-pit/2 27138 root txt unknown /proc/27138/exe

プロセスを眺めていたところ、/opt/kata/bin/firecracker --api-sock ~firecracker.sockというものを見つけ、なんかFirecrackerのエンドポイントっぽいように見える。


$ ps auxf



root 26244 0.1 0.9 1115404 76416 ? Ssl Feb19 2:34 /usr/bin/dockerd -H fd://
root 26268 0.3 0.4 1023028 35228 ? Ssl Feb19 4:19 \_ docker-containerd --config /var/run/docker/containerd/containerd.toml
root 27093 0.0 0.0 7500 4252 ? Sl Feb19 0:02 \_ docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/e2723b5c68c0af1c29f1f7f520db7267698daf63f0137fd4
root 27134 0.1 1.2 145956 92028 ? Sl Feb19 2:14 \_ /opt/kata/bin/firecracker --api-sock /run/vc/sbs/e2723b5c68c0af1c29f1f7f520db7267698daf63f0137fd44de54d1b3a01389e/firecracker.sock
root 27147 0.0 0.1 615524 14720 pts/0 Ssl+ Feb19 0:00 \_ /opt/kata/libexec/kata-containers/kata-shim -agent vsock://3472509929:1024 -container e2723b5c68c0af1c29f1f7f520db7267698daf63f0137fd44de54d1b3a01389e -exec-id e2

$ cd /run/vc/sbs/e2723b5c68c0af1c29f1f7f520db7267698daf63f0137fd44de54d1b3a01389e/

root@kata-testing:/run/vc/sbs/e2723b5c68c0af1c29f1f7f520db7267698daf63f0137fd44de54d1b3a01389e
$ ll firecracker.sock
srwxr-xr-x 1 root root 0 Feb 19 14:04 firecracker.sock=


$ sudo curl --unix-socket firecracker.sock -i http://localhost/
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 20 Feb 2019 12:39:36 GMT

{"id":"anonymous-instance","state":"Running"}root@kata-testing:/run/vc/sbs/e2723b5c68c0af1c29f1f7f520db7267698daf63f0137fd44de54d1b3a01389e

RESTでアクセスすると応答が返ってきました。

Kataからもここを経由して制御しているんでしょうかね。

sudo curl --unix-socket firecracker.sock -i http://localhost/machine-config

HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 20 Feb 2019 12:43:15 GMT

{ "vcpu_count": 1, "mem_size_mib": 128, "ht_enabled": false, "cpu_template": "Uninitialized" }root@kata-testing:/run/vc/sbs/e2723b5c68c0af1c29f1f7f520db7267698daf63f0137fd44de54d1b3a01389e

ちなみに同じパスにいくつかjsonファイルが置かれていてこれが構成ファイルになっているようでした。


$ ll
total 20
drwxr-x--- 4 root root 220 Feb 19 14:04 ./
drwxr-x--- 3 root root 60 Feb 19 14:04 ../
-rw-r--r-- 1 root root 46 Feb 19 14:04 agent.json
-rw-r--r-- 1 root root 420 Feb 19 14:04 devices.json
drwxr-x--- 2 root root 120 Feb 19 14:04 e2723b5c68c0af1c29f1f7f520db7267698daf63f0137fd44de54d1b3a01389e/
srwxr-xr-x 1 root root 0 Feb 19 14:04 firecracker.sock=
-rw-r--r-- 1 root root 13 Feb 19 14:04 hypervisor.json
-rw-r--r-- 1 root root 0 Feb 19 14:04 lock
-rw-r--r-- 1 root root 1980 Feb 19 14:04 network.json
-rw-r--r-- 1 root root 104 Feb 19 14:04 state.json
drwxr-x--- 2 root root 200 Feb 19 14:04 tempDir/


$ cat hypervisor.json | jq
{
"PID": 27134
}

$ cat state.json | jq

{
"state": "running",
"BlockDeviceID": "",
"blockIndex": 1,
"fstype": "",
"pid": 27147,
"guestMemoryBlockSize": 128
}


$ cat agent.json | jq
{
"ProxyPid": 0,
"URL": "vsock://3472509929:1024"
}


$ cat devices.json | jq
[
{
"Type": "block",
"Data": {
"ID": "d852841c08719cf6",
"DeviceInfo": {
"HostPath": "/dev/dm-1",
"DevType": "b",
"Major": 253,
"Minor": 1,
"FileMode": 0,
"UID": 0,
"GID": 0,
"ID": "d852841c08719cf6",
"DriverOptions": {
"block-driver": "virtio-mmio"
}
},
"RefCount": 1,
"AttachCount": 1,
"BlockDrive": {
"File": "/dev/dm-1",
"Format": "raw",
"ID": "drive-d852841c08719cf6",
"Index": 0,
"MmioAddr": "",
"PCIAddr": "",
"SCSIAddr": "",
"NvdimmID": "",
"VirtPath": "/dev/vdb"
}
}
}
]

$ cat network.json | jq

{
"NetNsPath": "/var/run/netns/cni-c24982d5-d4fe-5e54-1e8f-318bf2aba489",
"NetNsCreated": true,
"Endpoints": [
{
"Type": "virtual",
"Data": {
"NetPair": {
"ID": "970f73a7-b1bb-4ccc-8ac4-1c8446e2eb79",
"Name": "br0_kata",
"TAPIface": {
"Name": "tap0_kata",
"HardAddr": "02:42:ac:11:00:02",
"Addrs": null
},
"VMFds": null,
"VhostFds": [],
"VirtIface": {
"Name": "eth0",
"HardAddr": "f6:46:86:dd:52:f0",
"Addrs": null
},
"NetInterworkingModel": 4
},
"EndpointProperties": {
"Iface": {
"Index": 6,
"MTU": 1500,
"TxQLen": 0,
"Name": "eth0",
"HardwareAddr": "AkKsEQAC",
"Flags": 19,
"RawFlags": 69699,
"ParentIndex": 7,
"MasterIndex": 0,
"Namespace": null,
"Alias": "",
"Statistics": {
"RxPackets": 2,
"TxPackets": 0,
"RxBytes": 180,
"TxBytes": 0,
"RxErrors": 0,
"TxErrors": 0,
"RxDropped": 0,
"TxDropped": 0,
"Multicast": 0,
"Collisions": 0,
"RxLengthErrors": 0,
"RxOverErrors": 0,
"RxCrcErrors": 0,
"RxFrameErrors": 0,
"RxFifoErrors": 0,
"RxMissedErrors": 0,
"TxAbortedErrors": 0,
"TxCarrierErrors": 0,
"TxFifoErrors": 0,
"TxHeartbeatErrors": 0,
"TxWindowErrors": 0,
"RxCompressed": 0,
"TxCompressed": 0
},
"Promisc": 0,
"Xdp": {
"Fd": 0,
"Attached": false,
"Flags": 0,
"ProgId": 0
},
"EncapType": "ether",
"Protinfo": null,
"OperState": 6,
"NetNsID": 0,
"NumTxQueues": 0,
"NumRxQueues": 0,
"Type": "veth"
},
"Addrs": [
{
"IP": "172.17.0.2",
"Mask": "//8AAA==",
"Label": "eth0",
"Flags": 128,
"Scope": 0,
"Peer": {
"IP": "172.17.0.2",
"Mask": "//8AAA=="
},
"Broadcast": "172.17.255.255",
"PreferedLft": 4294967295,
"ValidLft": 4294967295
}
],
"Routes": [
{
"LinkIndex": 6,
"ILinkIndex": 0,
"Scope": 0,
"Dst": null,
"Src": "",
"Gw": "172.17.0.1",
"MultiPath": null,
"Protocol": 3,
"Priority": 0,
"Table": 254,
"Type": 1,
"Tos": 0,
"Flags": 0,
"MPLSDst": null,
"NewDst": null,
"Encap": null,
"MTU": 0,
"AdvMSS": 0
},
{
"LinkIndex": 6,
"ILinkIndex": 0,
"Scope": 253,
"Dst": {
"IP": "172.17.0.0",
"Mask": "//8AAA=="
},
"Src": "172.17.0.2",
"Gw": "",
"MultiPath": null,
"Protocol": 2,
"Priority": 0,
"Table": 254,
"Type": 1,
"Tos": 0,
"Flags": 0,
"MPLSDst": null,
"NewDst": null,
"Encap": null,
"MTU": 0,
"AdvMSS": 0
}
],
"DNS": {
"Servers": null,
"Domain": "",
"Searches": null,
"Options": null
}
},
"Physical": false,
"EndpointType": "virtual",
"PCIAddr": ""
}
}
]
}

まあ、検証なり商用なりで使ってみないと違いや良し悪しはわかりませんな。