Open2

Cloud Hypervisorを試す

ISATOISATO

Cloud Hypervisorとは

Intelが開発を進め、現在はLinux Foundation傘下のVMM。
クラウドのワークロードにフォーカスしており、サポートするアーキテクチャはx86-64とAArch64

時期的には、CrosVM→Firecracker→(rust-vmm)→Cloud Hypervisor ぐらいで登場しているらしい。

公式ページ: https://www.cloudhypervisor.org/

試す

目標

  • Cloudhypervisorで作ったVMでnginxを動かし、別のマシンからアクセスする

環境

ubuntu@cloudhv:~$ cat /etc/os-release | head -1
PRETTY_NAME="Ubuntu 22.04.4 LTS"
ubuntu@cloudhv:~$

準備

実行に必要なパッケージをinstall

sudo apt install qemu-utils mtools bridge-utils uml-utilities

UbuntuのCloud ImageをDownload

cd $HOME
wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw
wget https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases/download/0.4.2/hypervisor-fw

Cloud HypervisorのバイナリをDownload。~/bin ディレクトリにおいておく

mkdir bin
cd bin
wget https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v39.0/cloud-hypervisor-static
wget https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v39.0/ch-remote-static
cd

cloud-hypervisor-static バイナリに対して、capabilityと実行権限を設定する。

 sudo setcap cap_net_admin+ep bin/cloud-hypervisor-static
chmod +x bin/*

cloud imageのための、cloudinitのconfigを生成する

git clone https://github.com/cloud-hypervisor/cloud-hypervisor.git
cd cloud-hypervisor/
bash scripts/create-cloud-init.sh

VMを起動する

まずはCPUとメモリを味わう

最低限の準備ができたので、まずはVMをbootさせてみる。

ubuntu@cloudhv:~$ ./bin/cloud-hypervisor-static \
        --kernel ./hypervisor-fw \
        --disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
        --cpus boot=4 \
        --memory size=1024M

Ubuntu 20.04.6 LTS cloud hvc0

cloud login: cloud
Password:
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-177-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

  System information as of Wed May  1 08:24:14 UTC 2024

  System load: 1.35              Memory usage: 21%   Processes:       140
  Usage of /:  69.3% of 1.96GB   Swap usage:   0%    Users logged in: 0

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

cloud@cloud:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.6 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
cloud@cloud:~$ nproc
4
cloud@cloud:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:          964Mi       144Mi       345Mi       0.0Ki       473Mi       665Mi
Swap:            0B          0B          0B
cloud@cloud:~$

いい感じ。

VMは ps からプロセスIDを探してきてkillして終わらせる。

ch-remoteコマンドを使う

このままだと、VMの操作が不便なので ch-remote コマンドを使う。

--api-socket オプションを起動してVMを起動する

ubuntu@cloudhv:~$ ./bin/cloud-hypervisor-static \
        --kernel ./hypervisor-fw \
        --disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
        --cpus boot=4 \
        --memory size=1024M \
+        --api-socket path=/tmp/cloudhv.socks

Ubuntu 20.04.6 LTS cloud hvc0

cloud login:

この状態で以下のコマンドを打つと、いい感じの操作ができるようになる

 ubuntu@cloudhv:~$ ./bin/ch-remote-static --api-socket /tmp/cloudhv.socks ping
{"build_version":"v39.0.0","version":"39.0.0","pid":1948,"features":["io_uring","kvm","mshv"]}
ubuntu@cloudhv:~$

NWを仕込む

目標とするNW構成

以下に示す画像のような構成を取る。

VMを起動するホストマシンと同じネットワークにVMを属させるため、
ホストマシン上でbridgeを作成し、そのbridgeに対して物理NICとVMに対応するtapデバイスを紐づける。

VMの設定

cloudinitで設定されるVMの NWの設定を以下のように変える。
これは、$HOMEにcloneした、cloudhypervisorのソース内のファイルを変更している。

diff --git a/test_data/cloud-init/ubuntu/local/network-config b/test_data/cloud-init/ubuntu/local/network-config
index 99df95a7..95353b39 100644
--- a/test_data/cloud-init/ubuntu/local/network-config
+++ b/test_data/cloud-init/ubuntu/local/network-config
@@ -3,5 +3,9 @@ ethernets:
   ens4:
     match:
        macaddress: 12:34:56:78:90:ab
-    addresses: [192.168.249.2/24]
-    gateway4: 192.168.249.1
+    addresses: [192.168.11.215/24]
+    gateway4: 192.168.11.1
+    nameservers:
+        addresses:
+          - 192.168.11.3

設定をimgに書き出す

ubuntu@cloudhv:~/cloud-hypervisor$ bash scripts/create-cloud-init.sh

前の設定が残っているdiskを消して再生成する

cd $HOME
rm focal-server-cloudimg-amd64.raw
qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw

これでMACアドレスを指定して起動する。

ubuntu@cloudhv:~$ ./bin/cloud-hypervisor-static \
        --kernel ./hypervisor-fw \
        --disk path=focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
        --cpus boot=4 \
        --memory size=1024M \
+        --net "mac=12:34:56:78:90:ab" \
        --api-socket path=/tmp/cloudhv.socks

Ubuntu 20.04.6 LTS cloud hvc0

cloud login: cloud
Password:
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-177-generic x86_64)

~~~snip ~~~~

cloud@cloud:~$ ip -br a
lo               UNKNOWN        127.0.0.1/8 ::1/128
ens4             UP             192.168.11.215/24 fe80::1034:56ff:fe78:90ab/64
cloud@cloud:~$

ここまでで、VM内部でIPは設定されたが、外に疎通はできない状態。

ホストマシンの設定

次にホストマシンの設定を行う。
ホストマシンの設定では、主に以下を行う。

  1. tapデバイスの作成
  2. bridgeの作成・設定
  3. 物理NICの設定とbridgeへの接続
  4. bridgeにtapデバイスを接続する

1. tapデバイスの作成

sudo tunctl -t chvtap0 ubuntu

2. bridgeの作成・設定

ubuntu@cloudhv:~$ sudo brctl addbr br0
ubuntu@cloudhv:~$ sudo ip addr add 192.168.11.214/24 dev br0
ubuntu@cloudhv:~$ ip -br a
lo               UNKNOWN        127.0.0.1/8 ::1/128
ens3             UP             192.168.11.214/24 metric 100 fe80::f816:3eff:feda:4532/64
chvtap0          UP             fe80::4093:93ff:fe9e:d36/64
br0              DOWN           192.168.11.214/24
ubuntu@cloudhv:~$

3. 物理NICの設定とbridgeへの接続

前までの手順で、bridgeに物理NICのIPを移動する準備をした。
次に、以下のコマンドを実行し、ens3をプロミスキャスモードに変更し、bridgeを有効にする。

sudo ip link set ens3 promisc on && \
sudo ip addr flush dev ens3 && \
sudo brctl addif br0 ens3 && \
sudo ip link set up br0

4. bridgeにtapデバイスを接続する

sudo brctl addif br0 chvtap0

これで、VMから外のNWへ、同じNWの別の機器からVMへの疎通が可能になった。

VM側でnginxを入れる

cloud@cloud:~$ sudo apt install nginx

おわり!

参考文献