bhyve虚拟化运行Ubuntu
备注
在部署 xcloud
用于 cloud-atlas.dev
的后端基础运行环境,为后续 bhyve PCI Passthrough 准备,最终目标是实现 NVIDIA GPU 能够在FreeBSD的虚拟化环境中使用,构建 ollama 运行。
主机准备
内核vmm
在 bhyve
创建虚拟机之前需要加载加载 bhyve
内核模块:
kldload vmm
kldload nmdm
kldload if_tap
kldload if_bridge
并且确保启动时加载内核模块:
echo 'vmm_load="YES"' >> /boot/loader.conf
echo 'nmdm_load="YES"' >> /boot/loader.conf
echo 'if_tap_load="YES"' >> /boot/loader.conf
echo 'if_bridge_load="YES"' >> /boot/loader.conf
创建网桥和tap
在
/etc/sysctl.conf
中配置tap设备在操作系统启动时启动:
echo "net.link.tap.up_on_open=1" >> /etc/sysctl.conf
sysctl net.link.tap.up_on_open=1
创建网桥并连接网卡( 案例中使用的网卡设备是
igc0
)
# 创建tap设备
ifconfig tap0 create
# 创建多个tap设备,分别对应不同虚拟机内部虚拟网卡,规划为每个vm一个虚拟网卡设备,这里案例我一共添加了3个tap设备
ifconfig tap1 cteate
ifconfig tap2 cteate
# 创建 bridge0
ifconfig bridge0 create
# 网桥重命名为 igc0bridge
ifconfig bridge0 name igc0bridge
ifconfig igc0bridge up
# 可以连续使用 addm 添加多个设备到网桥,也可以拆分成一次addm一个设备
# 添加tap虚拟网卡设备连接到bridge
ifconfig bridge0 addm tap0 addm tap1 addm tap2
# 一共有4个Intel i226-v 2.5Gbps网卡,都配置到一个bridge上联通网络
ifconfig bridge0 addm igc0 addm igc1 addm igc2 addm igc3
# 现在虚拟网络和物理网卡接口就已经实现了完全的交换网络(平面型),可以测试网络连通性了
确保启动时激活:
/etc/rc.conf
中配置# 创建网桥以及用于虚拟机的tap虚拟网络设备
cloned_interfaces="bridge0 tap0 tap1 tap2"
# 重命名网桥
ifconfig_bridge0_name="igc0bridge"
# 将物理网卡(4个igcX)和虚拟网卡(tapX)连接到网桥上
ifconfig_igc0bridge="inet 192.168.7.201/24 addm igc0 addm igc1 addm igc2 addm igc3 addm tap0 addm tap1 addm tap2 up"
# 设置默认网关
defaultrouter="192.168.7.101"
# 激活物理网卡
ifconfig_igc0="up"
ifconfig_igc1="up"
ifconfig_igc2="up"
ifconfig_igc3="up"
虚拟磁盘
备注
我采用 ZFS 来构建本地存储
创建ZFS数据集
对于host主机具备 ZFS 环境的话, 使用ZFS volumes来代替磁盘镜像,可以获得明显的性能提升
在构建 cloud-atlas.dev
模拟环境中,已经完成了 ZFS Stripe条带化 (FreeBSD环境实践) 部署,所以具备了 zdata
存储池,在此基础上完成虚拟机磁盘创建:
创建
zdata/vms/ubuntu
:
zfs create -p zdata/vms
zfs set compression=lz4 zdata/vms
# 创建16G大小的 ZFS volume
# volmode=dev 表示这个ZFS volume(ZVOL)输出给操作系统时是作为 ``devfs`` 中的一个raw块设备(raw block device)
zfs create -V 16G -o volmode=dev zdata/vms/ubuntu
# 对于测试环境,为了节约磁盘可以使用稀疏卷(sparse volume),即创建卷时使用 -s 参数
# 这样raw disk不是马上分配,而是在数据写入时动态分配(可以分配远大于物理磁盘空间的虚拟磁盘,必要时再扩容底层zfs存储)
zfs create -sV 50G -o volmode=dev zdata/vms/ubuntu
备注
设置为 volmode=dev
的数据集不会自动挂载,所以在 /zdata/vms
目录下是空白的
下载安装iso
从ubuntu官网下载安装镜像:
curl https://mirrors.jxust.edu.cn/ubuntu-releases/24.04.2/ubuntu-24.04.2-live-server-amd64.iso -o ubuntu-24.04.2-live-server-amd64.iso
安装bhyve的Grub支持
通过 bhyveload
和 grub-bhyve
的插件, bhyve
hyperviosr可以使用UEFI firmware来启动虚拟机。这个选项可以用来支持那些特定的不支持其他loaders的guest操作系统。
grub
启动管理器是Linux guests启动建议的加载器,这样就能够运行 grub-bhyve
执行程序,也就是允许我们启动非FreeBSD guest操作系统:
pkg install grub2-bhyve bhyve-firmware
在安装了firmware之后,在 bhyve
命令行添加参数 -l bootrom,/path/to/firmware
来加载UEFI firmware
安装虚拟机
BIOS模式启动bhyve虚拟机
警告
我这里尝试失败,手册中使用镜像文件,我模仿改成zfs卷集,没有启动成功。待后续再尝试
创建一个设备映射文件以便grub能够将虚拟设备映射为host主机中的文件:
/zdata/vms/ubuntu.map
配置文件作为设备映射(hd0) /zdata/vms/ubuntu
(cd0) /zdata/docs/backup/software/ubuntu/ubuntu-24.04.2-live-server-amd64.iso
使用
grub2-bhyve
从ISO镜像中加载Linux内核:
grub2-bhyve
从ISO镜像中加载Linux内核grub-bhyve -m ubuntu.map -r cd0 -M 4096M ubuntu
此时就会在终端进入Linux安装的grub界面(安装镜像包含了一个 grub.cfg
)
GNU GRUB version 2.00
+-------------------------------------------------------------------------------+
|Try or Install Ubuntu Server |
|Ubuntu Server with the HWE kernel |
|Test memory |
| |
| |
| |
| |
| |
| |
+-------------------------------------------------------------------------------+
Use the ^ and v keys to select which entry is highlighted.
Press enter to boot the selected OS, `e' to edit the commands before
booting or `c' for a command-line.
使用UEFI Firmware启动bhyve虚拟机
bhyveload
和 grub-bhyve
为 bhyve
hypervisor 提供了使用UEFI firmware启动虚拟机的功能。(需要安装 bhyve-firmware
)
执行以下命令开始启动虚拟机安装:
# ubuntu
bhyve -AHP -c 2 -m 4G -w \
-s 0,hostbridge \
-s 3,ahci-cd,/zdata/docs/backup/software/ubuntu/ubuntu-24.04.2-live-server-amd64.iso \
-s 4,virtio-blk,/dev/zvol/zdata/vms/ubuntu \
-s 5,virtio-net,tap0 \
-s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd,/zdata/vms/ubuntu_BHYVE_UEFI_VARS.fd \
ubuntu
命令参数:
-c
设置虚拟机vcpu数量-H
输出给加载器的host文件系统-l
使用OS loader(对于非FreeBSD需要使用uefi)-m
设置虚拟机内存-w
忽略没有实现的MSRs-s
配置一个虚拟PCI slot 以及其他功能如硬盘,cdrom和其他设备-A
生成ACPI表,对于FreeBSD/amd64 guests需要-H
当检测到HLT指令是限制vcpu线程,如果该选项没有检测到,则vcpu可以使用100%的host CPU-P
当检测到PAUSE指令时强制guest虚拟机vcpu退出-s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait
提供了Graphical UEFI Framebuffer
,这对于图形安装界面非常有用,例如安装Windows就需要这个参数
VNC客户端连接
启动安装以后就可以使用 remmina
这样的VNC客户端俩皆 127.0.0.1:5900
来访问(如果是远程服务器,则使用服务器IP)

启动
备注
我在 bhyve快速起步 实践中提到了按照handbook,在上述安装过程结束时候需要复制 grubx64.efi
为 bootx64.efi
。但是我现在实践没有执行这步efi文件复制,看起来也能够启动虚拟机。
最后重启虚拟机,需要强制退出,然后再启动
强制虚拟机关机:
bhyvectl --destroy --vm=ubuntu
启动虚拟机(去除了cdrom配置):
start_ubuntu
# ubuntu 去除掉iso启动参数就能够直接启动
bhyve -AHP -c 2 -m 4G -w \
-s 0,hostbridge \
-s 4,virtio-blk,/dev/zvol/zdata/vms/ubuntu \
-s 5,virtio-net,tap0 \
-s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd,/zdata/vms/ubuntu_BHYVE_UEFI_VARS.fd \
ubuntu
生成虚拟机配置
上述启动虚拟机需要很长的命令行,为了方便启动,可以先把虚拟机配置dump出来,也就是修改上述 start_ubuntu
,添加一行 -o config.dump=1
参数,就可以输出配置(需要重定向到文件):
start_ubuntu
重定向输出vm配置# ubuntu 去除掉iso启动参数就能够直接启动
bhyve -AHP -c 2 -m 4G -w \
-s 0,hostbridge \
-s 4,virtio-blk,/dev/zvol/zdata/vms/ubuntu \
-s 5,virtio-net,tap0 \
-s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd,/zdata/vms/ubuntu_BHYVE_UEFI_VARS.fd \
-o config.dump=1 \
ubuntu > ubuntu.config
此时生成的配置文件 ubuntu.config
如下:
start_ubuntu
重定向输出vm配置文件 ubuntu.config
acpi_tables_in_memory=true
memory.size=4G
x86.vmexit_on_hlt=true
x86.vmexit_on_pause=true
x86.strictmsr=false
lpc.fwcfg=bhyve
lpc.com1.path=stdio
lpc.bootrom=/usr/local/share/uefi-firmware/BHYVE_UEFI.fd
lpc.bootvars=/zdata/vms/ubuntu_BHYVE_UEFI_VARS.fd
acpi_tables=true
cpus=2
pci.0.0.0.device=hostbridge
pci.0.4.0.device=virtio-blk
pci.0.4.0.path=/dev/zvol/zdata/vms/ubuntu
pci.0.5.0.device=virtio-net
pci.0.5.0.backend=tap0
pci.0.29.0.device=fbuf
pci.0.29.0.tcp=0.0.0.0:5900
pci.0.29.0.w=800
pci.0.29.0.h=600
pci.0.29.0.wait=true
pci.0.30.0.device=xhci
pci.0.30.0.slot.1.device=tablet
pci.0.31.0.device=lpc
config.dump=1
name=ubuntu
删除掉上述配置文件中
config.dump=1
行,就可以使用-k
参数来启动虚拟机:
-k
指定配置文件启动虚拟机bhyve -k ubuntu.config