启动
参考:
https://www.cloudhypervisor.org/docs/prologue/quick-start/#booting-linux
在 linux 上启动.
Cloud Hypervisor 支持直接内核启动(x86-64内核需使用支持PVH构建的内核)或通过固件/firmware启动(可选Rust Hypervisor固件或名为 CLOUDHV/CLOUDHV_EFI 的edk2 UEFI固件)。
最新版本的Rust Hypervisor固件及edk2存储库中均提供固件文件的二进制构建版本。
固件的选择取决于您的客户操作系统选项,可能需要进行一些实验性测试。
固件启动
Cloud Hypervisor 支持引导包含运行云工作负载所需全部组件的磁盘镜像,即云镜像。
准备工作
首先安装 qemu-utils,稍后要用到其中的 qemu-img 和 mkdosfs :
sudo apt install qemu-utils
sudo apt install dosfstools
sudo apt install mtools
以下示例命令将下载Ubuntu云镜像,将其转换为 Cloud Hypervisor 可用的格式,并生成引导该镜像所需的固件。
mkdir -p ~/work/soft/cloudhypervisor/fireware
cd ~/work/soft/cloudhypervisor/fireware
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.5.0/hypervisor-fw
处理完成后的文件列表:
$ ls -lh
total 2.1G
-rw-rw-r-- 1 sky sky 618M Jun 25 09:39 focal-server-cloudimg-amd64.img
-rw-r--r-- 1 sky sky 2.2G Oct 16 16:54 focal-server-cloudimg-amd64.raw
-rw-rw-r-- 1 sky sky 133K Nov 30 2024 hypervisor-fw
Ubuntu云镜像默认不提供密码,因此首次启动时必须使用 cloud-init 磁盘镜像进行镜像定制。本脚本可生成基础 cloud-init 镜像,为镜像预设默认用户名/密码为 cloud/cloud123 。仅需在首次启动时添加此磁盘镜像即可。脚本同时通过 --net “mac=12:34:56:78:90:ab,tap=” 选项,基于 test_data/cloud-init/ubuntu/local/network-config 配置信息分配默认IP地址。随后系统将根据 network-config 详情启用匹配MAC地址的网络接口。
准备需要的脚本, 在代码仓库根目录下的 scripts 中:
https://github.com/cloud-hypervisor/cloud-hypervisor/tree/v48.0/scripts
后面还要使用到 test_data/cloud-init/ubuntu/ 目录下的文件, 因此最好是把整个代码仓库下载下来,方便后面使用
mkdir -p ~/work/code/cloud-hypervisor/
cd ~/work/code/cloud-hypervisor/
git clone https://github.com/cloud-hypervisor/cloud-hypervisor.git
cd cloud-hypervisor
git checkout v50.0
执行:
~/work/code/cloud-hypervisor/cloud-hypervisor/scripts/create-cloud-init.sh
输出如下:
+ rm -f /tmp/ubuntu-cloudinit.img
+ mkdosfs -n CIDATA -C /tmp/ubuntu-cloudinit.img 8192
mkfs.fat 4.2 (2021-01-31)
+ mcopy -oi /tmp/ubuntu-cloudinit.img -s test_data/cloud-init/ubuntu/local/user-data ::
+ mcopy -oi /tmp/ubuntu-cloudinit.img -s test_data/cloud-init/ubuntu/local/meta-data ::
+ mcopy -oi /tmp/ubuntu-cloudinit.img -s test_data/cloud-init/ubuntu/local/network-config ::
这会生成一个 ubuntu-cloudinit.img 文件,大小为 8M:
$ ls -lh /tmp/ubuntu-cloudinit.img
-rw-rw-r-- 1 sky sky 8.0M Oct 16 17:12 /tmp/ubuntu-cloudinit.img
注意这个目录是 /tmp,重启之后文件很可能就不在了,方便起见, 还是复制到
mkdir -p ~/work/soft/cloudhypervisor/images
mv /tmp/ubuntu-cloudinit.img /home/sky/work/soft/cloudhypervisor/images
启动
注意: 从 v49 版本开始需要设置 cloud-hypervisor 二进制的特权, 执行命令:
sudo setcap cap_net_admin+ep /home/sky/work/code/cloud-hypervisor/cloud-hypervisor/target/x86_64-unknown-linux-musl/release/cloud-hypervisor
否则后面启动时会报错:
cloud-hypervisor: 0.016376s: <main> ERROR:/home/sky/work/code/cloud-hypervisor/cloud-hypervisor/src/lib.rs:23 -- Fatal error: VmBoot(VmBoot(DeviceManager(CreateVirtioNet(OpenTap(TapOpen(ConfigureTap(Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" })))))))
Error: Cloud Hypervisor exited with the following chain of errors:
0: Error booting VM
1: The VM could not boot
2: Error from device manager
3: Cannot create virtio-net device
4: Failed to open taps
5: Open tap device failed
6: Unable to configure tap interface
7: Operation not permitted (os error 1)
注意启动命令中的路径要用绝对路径,不能用 ‘~/’ 之类,否则会报错无法找到文件.
/home/sky/work/code/cloud-hypervisor/cloud-hypervisor/target/x86_64-unknown-linux-musl/release/cloud-hypervisor \
--kernel /home/sky/work/soft/cloudhypervisor/fireware/hypervisor-fw \
--disk path=/home/sky/work/soft/cloudhypervisor/fireware/focal-server-cloudimg-amd64.raw path=/home/sky/work/soft/cloudhypervisor/images/ubuntu-cloudinit.img \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask="
输出为:
cloud-hypervisor: 481.142000µs: <main> WARN:vmm/src/vm_config.rs:356 -- Deprecation warning: No IP address provided. A default IP address is assigned. This behavior will be deprecated soon.
cloud-hypervisor: 506.863000µs: <main> WARN:vmm/src/vm_config.rs:363 -- Deprecation warning: No network mask provided. A default network mask is assigned. This behavior will be deprecated soon.
Ubuntu 20.04.6 LTS cloud hvc0
cloud login:
输入前面设置的用户/密码 (cloud / cloud123), 登录进去, 如果要退出,执行 sudo shutdown now 命令关闭启动的 microVM 即可.
此时因为没有配置好网络, 所以登录进去 microVM 后会发现没有网络可用.
配置microVM的网络
没成功,等下继续.
首先要在主机上创建并配置 TAP 接口:
sudo ip tuntap add name vm-tap0 mode tap user $(whoami)
sudo ip link set vm-tap0 up
sudo ip addr add 192.168.1.127/24 dev vm-tap0
此时在主机上看到的 vm-tap0 设备为:
$ ip addr
......
10: vm-tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 3e:7b:2e:ca:9a:3e brd ff:ff:ff:ff:ff:ff
inet 192.168.1.127/24 scope global vm-tap0
valid_lft forever preferred_lft forever
注意:上面的 ip 命令在重启后会失效。若需持久化配置,可将其写入主机的网络配置文件(如 /etc/network/interfaces 或使用 systemd-networkd/NetworkManager)。
注意2: 如果配置有问题,可以先删除,再重新配置. sudo ip link delete vm-tap0
/home/sky/work/code/cloud-hypervisor/cloud-hypervisor/target/x86_64-unknown-linux-musl/release/cloud-hypervisor \
--kernel /home/sky/work/soft/cloudhypervisor/fireware/hypervisor-fw \
--disk path=/home/sky/work/soft/cloudhypervisor/fireware/focal-server-cloudimg-amd64.raw path=/tmp/ubuntu-cloudinit.img \
--cpus boot=4 \
--memory size=1024M \
--net "tap=vm-tap0,mac=12:34:56:78:90:22,ip=192.168.1.129,mask=255.255.255.0"
/home/sky/work/code/cloud-hypervisor/cloud-hypervisor/target/x86_64-unknown-linux-musl/release/cloud-hypervisor \
--kernel /home/sky/work/soft/cloudhypervisor/fireware/hypervisor-fw \
--disk path=/home/sky/work/soft/cloudhypervisor/fireware/focal-server-cloudimg-amd64.raw path=/home/sky/work/soft/cloudhypervisor/images/ubuntu-cloudinit.img \
--cpus boot=4 \
--memory size=1024M \
--net "tap=tap0,mac=12:34:56:78:90:22,ip=192.168.1.10,mask=255.255.255.0"
镜像启动
Cloud Hypervisor 也支持直接内核启动。对于 x86-64 架构,需要一个 vmlinux ELF 内核(编译时包含 PVH 支持)。为了支持开发,有一个自定义分支;不过只要所需选项已启用,任何近期的内核都可以使用。
构建 linux 内核
要构建内核:
cd ~/work/code/cloud-hypervisor/
git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b ch-6.12.8 linux-cloud-hypervisor
cd linux-cloud-hypervisor
make ch_defconfig
sudo apt install libelf-dev
sudo apt install bc
注意要执行 sudo apt install libelf-dev 命令安装 libelf,否则会报错:
<stdin>:1:10: fatal error: libelf.h: No such file or directory
构建 x86-64 kernel:
KCFLAGS="-Wa,-mx86-used-note=no" make bzImage -j `nproc`
构建完成后,linux 内核保存在 ./arch/x86/boot/compressed/vmlinux.bin,大小为 45M:
$ ls -lh ./arch/x86/boot/compressed/vmlinux.bin
-rwxrwxr-x 1 sky sky 45M Nov 18 15:50 ./arch/x86/boot/compressed/vmlinux.bin
rootfs 磁盘镜像可以用之前下载的 ubuntu 镜像, 之前存放在目录 ~/work/soft/cloudhypervisor/fireware 下
也可以再次下载和转换:
cd ~/work/soft/cloudhypervisor/fireware
wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img # x86-64
wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-arm64.img # AArch64
qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw # x86-64
qemu-img convert -p -f qcow2 -O raw focal-server-cloudimg-arm64.img focal-server-cloudimg-arm64.raw # AArch64
启动 vm:
/home/sky/work/code/cloud-hypervisor/cloud-hypervisor/target/x86_64-unknown-linux-musl/release/cloud-hypervisor \
--kernel /home/sky/work/code/cloud-hypervisor/linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \
--console off \
--serial tty \
--disk path=/home/sky/work/soft/cloudhypervisor/fireware/focal-server-cloudimg-amd64.raw \
--cmdline "console=ttyS0 root=/dev/vda1 rw" \
--cpus boot=4 \
--memory size=1024M \
--net "tap=,mac=,ip=,mask="