bhyve快速起步
主机准备
内核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
比较简单的虚拟机网络设置是为虚拟机内部的网络设备创建一个连接的 tap
接口,然后在host主机上创建一个 bridge
接口,并通过 bridge
接口来包含 tap
接口和 物理网卡
接口作为 members
。这样实现的虚拟网络就类似于Linux KVM 中 libvirt 网桥型网络 。
备注
第一次实践是,由于我在 FreeBSD无线网络BCM43602(通过wifibox) 使用了 wifibox
,实际上已经启动了 tap
设备以及虚拟化,并且也具备了 bridge
网桥。
不过,我再次实践时重新安装了一台FreeBSD服务器,实践本段 创建网桥和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"
警告
我的第一次实践因为是在 FreeBSD无线网络BCM43602(通过wifibox) 之后执行,当时已经有一个 wifibox
虚拟机,但是需要创建一个 tap1
设备( tap0
设备已经在之前由wifibox创建过了),并连接到 wifibox0
网桥(所以加了这段,你不需要):
tap1
连接 wifibox0
网桥# 创建tap设备,并连接到现有的wifibox0网桥上
ifconfig tap1 create
ifconfig wifibox0 addm tap1
设置启动时添加tap1:
#bhyve的tap启动
cloned_interfaces="tap1"
ifconfig_wifibox0="addm tap1 up"
虚拟磁盘
可以使用文件作为虚拟磁盘(类似 qcow2
镜像文件),或者结合 ZFS 来构建数据集(更好)
创建虚拟磁盘文件
创建虚拟机磁盘文件:
truncate -s 16G guest.img
创建ZFS数据集
对于host主机具备 ZFS 环境的话, 使用ZFS volumes来代替磁盘镜像,可以获得明显的性能提升
创建
zroot/vms/debian
:
zfs create -p zroot/vms
zfs set compression=lz4 zroot/vms
# 准备3个安装模版分别对应不同的虚拟机
zfs create -V16G -o volmode=dev zroot/vms/debian
zfs create -V16G -o volmode=dev zroot/vms/fedora
zfs create -V16G -o volmode=dev zroot/vms/freebsd
警告
如果同时在Host主机和虚拟机内部使用ZFS,需要避免两个系统缓存虚拟机内容时产生竞争内存压力。为了缓解这种情况,可以考虑将Host主机的ZFS设置为仅使用元数据缓存(指定虚拟机的特定 zvol
数据集)。以下命令案例是将 zroot/vms/freebsd
的zvol设置为仅缓存元数据(因为我准备在freebsd虚拟机中使用ZFS):
zfs set primarycache=metadata zroot/vms/freebsd
下载安装iso
从debian官网下载安装镜像:
curl https://chuangtzu.ftp.acc.umu.se/debian-cd/current/amd64/iso-cd/debian-12.8.0-amd64-netinst.iso -o debian-12.8.0-amd64-netinst.iso
下载Fedora安装镜像
curl https://download.fedoraproject.org/pub/fedora/linux/releases/42/Server/x86_64/iso/Fedora-Server-netinst-x86_64-42-1.1.iso -o Fedora-Server-netinst-x86_64-42-1.1.iso
下载FreeBSD安装镜像
curl https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/14.2/FreeBSD-14.2-RELEASE-amd64-bootonly.iso -o FreeBSD-14.2-RELEASE-amd64-bootonly.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
安装虚拟机
执行以下命令开始启动虚拟机安装:
# debian
bhyve -c 1 -m 2G -w -H \
-s 0,hostbridge \
-s 3,ahci-cd,/home/admin/debian-12.8.0-amd64-netinst.iso \
-s 4,virtio-blk,/dev/zvol/zroot/vms/debian \
-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 \
debian
# fedora
# 使用完整镜像安装,我尝试netinst失败(安装交互过程中无法调整安装源) Fedora-Server-netinst-x86_64-42-1.1.iso
bhyve -c 1 -m 2G -w -H \
-s 0,hostbridge \
-s 3,ahci-cd,/home/admin/Fedora-Server-dvd-x86_64-42-1.1.iso \
-s 4,virtio-blk,/dev/zvol/zroot/vms/fedora \
-s 5,virtio-net,tap1 \
-s 29,fbuf,tcp=0.0.0.0:5901,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 \
fedora
# freebsd
bhyve -c 1 -m 2G -w -H \
-s 0,hostbridge \
-s 3,ahci-cd,/home/admin/FreeBSD-14.2-RELEASE-amd64-bootonly.iso \
-s 4,virtio-blk,/dev/zvol/zroot/vms/freebsd \
-s 5,virtio-net,tap2 \
-s 29,fbuf,tcp=0.0.0.0:5902,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 \
freebsd
命令参数:
-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就需要这个参数
异常
BdsDxe: failed to load Boot0002 "UEFI Misc Device"
VNC客户端连接
启动安装以后就可以使用 remmina
这样的VNC客户端俩皆 127.0.0.1:5900
来访问(如果是远程服务器,则使用服务器IP)

安装要点
安装结束前,最后一步需要返回并选择 Execute a shell
加载一个终端,然后需要将debian的efi文件复制出来给FreeBSD加载:



复制debian的efi
mkdir /target/boot/efi/EFI/BOOT/
# copy file - workaround for bhyve grub package #
# Pay attention to destination file bootx64.efi #
cp /target/boot/efi/EFI/debian/grubx64.efi /target/boot/efi/EFI/BOOT/bootx64.efi
备注
复制后的 efi 文件名是 bootx64.efi
启动
最后重启虚拟机,需要强制退出,然后再启动
强制虚拟机关机:
bhyvectl --destroy --vm=debian
启动虚拟机:
bhyve -c 2 -m 1G -w -H \
-s 0,hostbridge \
-s 4,virtio-blk,/dev/zvol/zroot/vms/debian \
-s 5,virtio-net,tap1 \
-s 29,fbuf,tcp=0.0.0.0:5900,w=1024,h=768,wait \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
debian
简单的启动脚本:
#!/bin/sh
# Name: startdebianvm
# Purpose: Simple script to start my Debian 10 VM using bhyve on FreeBSD
# Author: Vivek Gite {https://www.cyberciti.biz} under GPL v2.x+
-------------------------------------------------------------------------
# Lazy failsafe (not needed but I will leave them here)
# 我简单修改适应我的环境
ifconfig tap1 create
ifconfig wifibox0 addm tap0
if ! kldstat | grep -w vmm.ko
then
kldload -v vmm
fi
if ! kldstat | grep -w nmdm.ko
then
kldload -v nmdm
fi
bhyve -c 1 -m 1G -w -H \
-s 0,hostbridge \
-s 4,virtio-blk,/dev/zvol/zroot/vms/debian \
-s 5,virtio-net,tap1 \
-s 29,fbuf,tcp=0.0.0.0:5900,w=1024,h=768 \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
debian
注意,在终端执行虚拟机启动脚本,关闭终端会导致虚拟机退出,所以需要使用 tmux多会话终端管理 这样的终端管理器执行
可以设置在系统重启后执行的crontab:
@reboot /path/to/startdebianvm