vm-bhyve
我在直接使用 bhyve
命令时遇到的问题是无法修订创建的虚拟机配置: 在 bhyve虚拟化运行Ubuntu 以及 bhyve PCI Passthrough快速起步 时尝试修订 -m
参数指定不同的内存大小都会报错。
Github: freebsd/vm-bhyve 是一个基于 Shell 的最小化依赖的 bhyve manager
,非常方便管理虚拟机
安装
安装
vm-bhyve
vm-bhyve
pkg install vm-bhyve bhyve-firmware
可以看到会依赖安装3个软件包:
vm-bhyve
会安装3个软件包New packages to be INSTALLED:
bhyve-firmware: 1.0_2 [FreeBSD]
edk2-bhyve: g202308_5 [FreeBSD]
vm-bhyve: 1.6.2 [FreeBSD]
创建存储:
创建
zdata/vms
ZFS 存储数据集,并且将默认recordsize
属性128K
调整为64K
创建
zdata/vms/.templates
存储用于创建VM的模版
zfs create zdata/vms
#zfs set recordsize=64K zdata/vms
zfs create zdata/vms/.config
zfs create zdata/vms/.img
zfs create zdata/vms/.iso
zfs create zdata/vms/.templates
在
/etc/rc.conf
中设置虚拟化支持:
/etc/rc.conf
支持虚拟化# needed for virtualization support
vm_enable="YES"
vm_dir="zfs:zdata/vms"
在
/boot/loader.conf
添加:
/boot/loader.conf
# needed for virtualization support
vmm_load="YES"
初始化:
vm init
初始化步骤会激活 /etc/rc.conf
的 vm-bhyve
并设置使用的数据集,可以看到 /zroot/bhyve
目录下创建了:
vm init
创建了zfs数据集目录root@xcloud:/zroot/bhyve # ls -lh
total 2
drwxr-xr-x 2 root wheel 4B Jul 22 23:56 .config
drwxr-xr-x 2 root wheel 2B Jul 22 23:56 .img
drwxr-xr-x 2 root wheel 2B Jul 22 23:56 .iso
drwxr-xr-x 2 root wheel 3B Jul 22 23:56 .templates
备注
我在构建 zdata/vms
zfs存储数据集时候,为每个 .xxx
目录构建了一个子存储卷。这个步骤不是必须的,我考虑是今后可以做隔离和quota。
在完成初始化之后,检查 /zdata/vms
下面的上述4个子目录,可以看到 .config
目录下有2个空文件:
.config
目录下有2个空文件-rw-r--r-- 1 root wheel 0B Jul 24 16:42 null.iso
-rw-r--r-- 1 root wheel 0B Jul 24 16:42 system.conf
而在 .templates
目录下则有一个 default.conf
内容如下:
.templates
目录下 default.conf
loader="bhyveload"
cpu=1
memory=256M
network0_type="virtio-net"
network0_switch="public"
disk0_type="virtio-blk"
disk0_name="disk0.img"
在
/usr/local/share/examples/vm-bhyve/
目录下有虚拟机的配置模版案例,所谓的配置模版其实是一些简单的配置项来指定虚拟机如何运行。对于vm-bhyve
使用的模版是存放在$vm_dir/.templates
,所以执行以下命令复制模版:
cp /usr/local/share/examples/vm-bhyve/* /zdata/vms/.templates/
备注
复制模版文件中有一个 config.sample
包含了详细的配置解析,可以参考这个配置案例来修订自己的配置文件
使用
参考 config.sample
,我尝试定制自己的模版文件来实现 bhyve
虚拟机构建:
使用
uefi
来加载虚拟机环境指定
/zdata/vms/<vm_name>
的 ZFS 数据集来作为虚拟机存储磁盘指定 FreeBSD bridge快速起步 和 bhyve快速起步 构建的一个共用虚拟交换机
igc0bridge
虚拟交换机
默认情况下可以创建一个
public
虚拟机交换机,然后将物理主机的某个网卡加入(例如em0
),这样后续配置虚拟机的时候,只要为虚拟机指定这个public
虚拟机交换机,那么虚拟机的虚拟网卡就会连接上public
虚拟交换机,并通过em0
网卡连接外部物理真实网络:
vm switch create public
vm switch add public em0
不过,我的实践有所不同: 我已经在 FreeBSD bridge快速起步 和 bhyve快速起步 实践时构建了一个共用的虚拟交换机 igc0bridge
,也就是在 /etc/rc.conf
中配置了:
/etc/rc.conf
中配置虚拟交换机 igc0bridge
# 创建网桥以及用于虚拟机的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"
所以在 vm-bhyve
中复用这个虚拟交换机: vm-hbyve
在模版文件中设置 network0_switch="igc0bridge"
来指定
存储
在
vm create
命令时可以通过-d <datastore>
指定和默认vm_dir
不一样的ZFS存储数据集,例如我的/etc/rc.conf
配置了vm_dir="zfs:zdata/vms"
,但是我如果想要在另外一个zstore/bhyve
数据集中创建一个虚拟机,则可以使用( ⚠️ 我还没有验证):vm create -d zstore/bhyve ...
在 bhyve虚拟化运行Ubuntu 实践中,我使用了 ZFS volume 来作为虚拟机的磁盘,这种 raw disk 可以提高存储性能。不过实验环境也可以使用
zfs create -sV 50G -o volmode=dev ...
来构建稀疏卷(sparse volume)来节约存储空间占用
警告
⚠️
不需要预先为 vm-bhyve
手工创建 稀疏卷(sparse volume) ,因为其内置了创建功能,而且约定了:
DEVICE TYPE DISK NAME BHYVE PATH USED
zvol|sparse-zvol 'disk0' -> '/dev/zvol/pool/dataset/path/guest/disk0'
也就是说,只要配置了:
disk0_dev="sparse-zvol"
disk0_name="disk0"
就会自动在 /zdata/vms/mdev
目录下创建一个 disk0
稀疏卷(这里 zdata/vms
是指定的虚拟机卷集, mdev
是虚拟机名
bhyve PCI Passthrough
vm-bhyve
支持 bhyve PCI Passthrough ,并且可以检查系统中哪些设备可以passthrough:
vm passthru
我的 Nvidia Tesla P10 GPU运算卡 已经在 :ref:`` 配置好passthrough,所以输出现实状态已经就绪:
DEVICE BHYVE ID READY DESCRIPTION
hostb0 0/0/0 No 8th Gen Core 4-core Workstation Processor Host Bridge/DRAM Registers [Coffee Lake
S]
pcib1 0/1/0 No 6th-10th Gen Core Processor PCIe Controller (x16)
pcib2 0/1/1 No Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x8)
pcib3 0/1/2 No Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x4)
vgapci0 0/2/0 No CoffeeLake-S GT2 [UHD Graphics P630]
...
ppt0 1/0/0 Yes GP102GL [Tesla P10]
nvme0 2/0/0 No NVMe SSD
nvme1 3/0/0 No NVMe SSD
nvme2 5/0/0 No NVMe SSD
igc0 6/0/0 No Ethernet Controller I226-V
igc1 7/0/0 No Ethernet Controller I226-V
igc2 8/0/0 No Ethernet Controller I226-V
igc3 9/0/0 No Ethernet Controller I226-V
nvme3 10/0/0 No NVMe SSD
此时配置文件就可以设置:
passthru0="1/0/0=2:0"
备注
vm-bhyve
参考手册中, vm passthru
没有任何参数,只能显示当前可以passthrough的设备列表。似乎只有配置文件能够指定传递的设备
启动设备
vm-bhyve
配置中使用了一个 start_slot
参数和 install_slot
参数:
对于UEFI虚拟机,一些UEFI虚拟机要求磁盘slot是
3-6
,vm-bhyve
默认使用4
作为磁盘slot,而3
保留给安装ISO
VNC图形界面
vm-bhyve
提供了一个 graphics
参数来支持VNC,端口从5900开始找寻,通过 vm list|info
输出可以看到虚拟机的VNC端口:
# 默认提供VNC
graphics="yes"
配置
在
/zdata/vms/.templates
构建一个我的自定义模版x-vm.conf
:
x-vm.conf
loader="uefi"
cpu=4
memory=16G
wired_memory="yes"
network0_type="virtio-net"
network0_switch="igc0bridge"
network0_device="tap0"
disk0_name="disk0"
disk0_dev="sparse-zvol"
disk0_type="virtio-blk"
disk0_size="50G"
#passthru0="1/0/0=2:0"
graphics="yes"
graphics_listen="0.0.0.0"
graphics_port="5900"
配置说明:
wired_memory
是因为 bhyve PCI Passthrough 需要disk0_dev
指定为sparse-zvol
,这样vm-bhyve
会自动创建/zdata/vms/mdev
作为虚拟机存储数据集,并在下面创建一个sparse volume
raw磁盘disk0
network0_switch
指定了我预先配置的igc0bridge
虚拟交换机network0_device
这里设置了tap0
而不是让vm-bhyve
自动生成,是因为我发现我配置了指定交换机之后,自动生成的tap3
没有addm
到我指定的igc0bridge
虚拟交换机,导致网络不通。我参考config.sample
特定指定了我之前配置好的tap0
(已经连接在igc0bridge
上)就解决了这个网络问题我发现初次安装的时候不能直接把 Nvidia Tesla P10 GPU运算卡 直接 passthru 进虚拟机,会导致虚拟机启动后VNC没有输出(估计虚拟机发现有NVIDIA Nvidia Tesla P10 GPU运算卡 导致默认输出到GPU上了。这里注销掉GPU就能安装,后续安装完再修订配置加入 pcie passthru
创建虚拟机:
mdev
vm create -t x-vm -s 60G mdev
-t x-vm
表示使用 /zdata/vms/.templates
目录下的 x-vm.conf
作为模版,我这里使用了 -s 60G
创建了一个特定的60G虚拟磁盘,配置中默认我设置了 50G
在上述创建了虚拟机之后,就可以看到ZFS构建了一个
zdata/vms/mdev
存储集,并且在这个存储集下有一个disk0
的zvol
raw disk:
mdev
对应的ZFSroot@xcloud:~ # df -h
Filesystem Size Used Avail Capacity Mounted on
...
zdata/vms/mdev 4.4T 116K 4.4T 0% /zdata/vms/mdev
root@xcloud:~ # zfs list | grep vms
zdata/vms 784K 4.39T 120K /zdata/vms
...
zdata/vms/mdev 172K 4.39T 116K /zdata/vms/mdev
zdata/vms/mdev/disk0 56K 4.39T 56K -
vm-bhyve
提供了一个vm iso
命令用于将镜像下载到.iso
目录下(对于我的环境是/zdata/vms/.iso
),也可以手工将已经下载的镜像iso文件移动到该目录(我在该目录下保存了我下载的ubuntu-24.04.2-live-server-amd64.iso
)安装ubuntu:
vm install mdev ubuntu-24.04.2-live-server-amd64.iso
终端输出显示:
Starting mdev
* found guest in /zdata/vms/mdev
* booting...
虚拟机配置修改
我需要实现 bhyve PCI Passthrough ,所以修订虚拟机配置 /zdata/vms/mdev/mdev.conf
(这个配置是 vm create
时创建的):
/zdata/vms/mdev/mdev.conf
loader="uefi"
cpu=4
memory=16G
wired_memory="yes"
network0_type="virtio-net"
network0_switch="igc0bridge"
network0_device="tap0"
disk0_name="disk0"
disk0_dev="sparse-zvol"
disk0_type="virtio-blk"
passthru0="1/0/0=2:0"
graphics="yes"
graphics_listen="0.0.0.0"
graphics_port="5900"
uuid="ece97590-689f-11f0-a949-0003ee002989"
network0_mac="58:9c:fc:09:6b:0a"
奇怪,启动虚拟机VNC控制台没有任何输出
我检查了 /zdata/vms/mdev/vm-bhyve.log
:
vm-bhyve.log
日志没有看出报错Jul 24 23:47:31: initialising
Jul 24 23:47:31: [loader: uefi]
Jul 24 23:47:31: [cpu: 4]
Jul 24 23:47:31: [memory: 16G]
Jul 24 23:47:31: [hostbridge: standard]
Jul 24 23:47:31: [com ports: com1]
Jul 24 23:47:31: [uuid: ece97590-689f-11f0-a949-0003ee002989]
Jul 24 23:47:31: [debug mode: no]
Jul 24 23:47:31: [primary disk: disk0]
Jul 24 23:47:31: [primary disk dev: sparse-zvol]
Jul 24 23:47:31: initialising network device tap0
Jul 24 23:47:31: failed to find virtual switch 'igc0bridge'
Jul 24 23:47:31: booting
Jul 24 23:47:31: [bhyve options: -c 4 -m 16G -AHPw -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd -S -U ece97590-689f-11f0-a949-0003ee002989 -u -S]
Jul 24 23:47:31: [bhyve devices: -s 0,hostbridge -s 31,lpc -s 4:0,virtio-blk,/dev/zvol/zdata/vms/mdev/disk0 -s 5:0,virtio-net,tap0,mac=58:9c:fc:09:6b:0a -s 2:0,passthru,1/0/0 -s 7:0,fbuf,tcp=0.0.0.0:5900]
Jul 24 23:47:31: [bhyve console: -l com1,/dev/nmdm-mdev.1A]
Jul 24 23:47:31: starting bhyve (run 1)
我加上了debug模式,但是输出的日志没有变化
另外 Experience from bhyve (FreeBSD 14.1) GPU passthrough with Windows 10 guest 提到了将slot修改为8,我也尝试了不行:
#passthru0="1/0/0=8:0"
passthru0="1/0/0"
如果不指定slot参数,会自动找一个可用的,我发现是 6:0
:
passthru0="1/0/0"
Jul 25 00:15:05: [bhyve options: -c 4 -m 16G -AHPw -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd -S -U ece97590-689f-11f0-a949-0003ee002989 -u -S]
Jul 25 00:15:05: [bhyve devices: -s 0,hostbridge -s 31,lpc -s 4:0,virtio-blk,/dev/zvol/zdata/vms/mdev/disk0 -s 5:0,virtio-net,tap0,mac=58:9c:fc:09:6b:0a -s 6:0,passthru,1/0/0 -s 7:0,fbuf,tcp=0.0.0.0:5900]
Jul 25 00:15:05: [bhyve console: -l com1,/dev/nmdm-mdev.1A]
Jul 25 00:15:05: starting bhyve (run 1)
但是还是VNC没有任何输出黑屏。这个问题我一直没有解决,我尝试 在bhyve中实现NVIDIA GPU passthrough 来解决 Nvidia Tesla P10 GPU运算卡 passthru没有成功,但是发现同样的配置 Nvidia Tesla P4 GPU运算卡 是正常工作的。此问题待排查
虚拟机重命名
vm-bhyve
提供了 rename
指令可以重命名虚拟机,并且对于 ZFS 存储,可以非常丝滑地转换zfs存储集地名字以及对应地配置,所以不需要人工干预处理,非常实用:
vm-bhyve rename mdev xdev