24.6.使用 FreeBSD 上的 bhyve 虚拟机¶
BSD 许可的 bhyve 虚拟机管理器随着 FreeBSD 10.0-RELEASE 开始成为底层系统的一部分。这个虚拟机管理器支持数种客户机,包括 FreeBSD,OpenBSD 和数个 Linux® 发行版。默认情况下,bhyve 提供对串行控制台的访问而不模拟图形化控制台。其利用较新的 CPU 上的虚拟化 offload 功能来避免使用过时方法翻译指令和手动管理内存映射。
bhyve 在设计上需要支持 Intel® 扩展页表(EPT)或 AMD® 快速虚拟化索引(RVI)或 Nested 页表(NPT)的 CPU。以超过一枚 vCPU 运行 Linux 或者 FreeBSD 客户机需要 VMX unrestricted 模式(UG)支持。大多数新的处理器,特别是 Intel® Core™ i3/i5/i7 和 Intel® Xeon™ E3/E5/E7 都支持这些功能。对 UG 的支持是从 Intel® 的 Westmere 微架构引入的。若要查阅一份完整的支持 EPT 的 Intel® 处理器列表,请参见 https://ark.intel.com/content/www/us/en/ark/search/featurefilter.html?productType=873&0_ExtendedPageTables=True。RVI 在第三代以及之后的 AMD Opteron™(Barcelona)处理器中应用。判断处理器是否支持 bhyve 的方法是运行 demsg
,或者在 /var/run/dmesg.boot 中的 Feature2
一行查找 POPCNT
处理器功能标识(针对 AMD® 处理器);或者在 VT-x
一行查找 EPT
和 UG
处理器功能标识(针对 Intel® 处理器)。
24.6.1.准备宿主机¶
在 bhyve 中创建虚拟机的第一步是配置宿主操作系统。首先,加载 bhyve 内核模块:
# kldload vmm
然后,创建 tap
接口以供虚拟机中的网络设备进行连接。为了让该网络设备加入网络,另外创建一个桥接接口,其中包含 tap
接口和物理网络接口作为成员。在下面的例子中,物理网络接口为 igb0
:
# ifconfig tap0 create
# sysctl net.link.tap.up_on_open=1
net.link.tap.up_on_open: 0 -> 1
# ifconfig bridge0 create
# ifconfig bridge0 addm igb0 addm tap0
# ifconfig bridge0 up
24.6.2.创建一个 FreeBSD 客户机¶
创建一个文件用作客户机的虚拟磁盘。指定这个虚拟磁盘的大小和名称:
# truncate -s 16G guest.img
下载 FreeBSD 的安装镜像:
# fetch https://download.freebsd.org/releases/ISO-IMAGES/13.1/FreeBSD-13.1-RELEASE-amd64-bootonly.iso
FreeBSD-13.1-RELEASE-amd64-bootonly.iso 366 MB 16 MBps 22s
FreeBSD 附带了一个在 bhyve 中运行虚拟机的示例脚本。这个脚本将会启动虚拟机并循环执行,所以可在其崩溃时自动重新启动。这个脚本可接受数个选项来配置虚拟机:-c
控制虚拟 CPU 的数量,-m
限制客户机的可用内存,-t
定义使用的 tap 设备,-d
指定其使用的磁盘镜像,-i
控制 bhyve 从 CD 镜像引导,而非从磁盘引导,-I
指定要使用的 CD 镜像。最后一个参数是虚拟机的名称,该名称将被用来追踪运行中的虚拟机。这个例子将在安装模式下启动虚拟机:
# sh /usr/share/examples/bhyve/vmrun.sh -c 1 -m 1024M -t tap0 -d guest.img -i -I FreeBSD-13.1-RELEASE-amd64-bootonly.iso guestname
这个虚拟机将会引导并启动安装器。在虚拟机中完成系统安装并进入最后阶段,当系统提示是否进入 shell 时,选择 Yes。
重新启动虚拟机。重启会导致 bhyve 退出,这时循环执行 bhyve
的 vmrun.sh 脚本会自动重启虚拟机。这时请从引导器菜单中选择重启来跳出循环。之后,客户机就可以从虚拟磁盘中启动了:
# sh /usr/share/examples/bhyve/vmrun.sh -c 4 -m 1024M -t tap0 -d guest.img guestname
24.6.3.创建一个 Linux® 客户机¶
要引导进入 FreeBSD 以外的系统,必须先安装 port sysutils/grub2-bhyve。
接下来,创建一个文件用作客户机的虚拟磁盘:
# truncate -s 16G linux.img
使用 bhyve 启动虚拟机分为两个步骤。首先要加载一个内核,然后启动客户机。通过 sysutils/grub2-bhyve 加载 Linux® 内核。创建 device.map 令 grub 将虚拟设备映射到宿主机上的镜像文件:
(hd0) ./linux.img
(cd0) ./somelinux.iso
使用 sysutils/grub2-bhyve 从 ISO 文件中加载 Linux® 内核:
# grub-bhyve -m device.map -r cd0 -M 1024M linuxguest
这将启动 grub。如果安装 CD 中包含 grub.cfg,将会显示一个菜单;否则你需要手动指明并加载 vmlinuz
和 initrd
文件:
grub> ls
(hd0) (cd0) (cd0,msdos1) (host)
grub> ls (cd0)/isolinux
boot.cat boot.msg grub.conf initrd.img isolinux.bin isolinux.cfg memtest
splash.jpg TRANS.TBL vesamenu.c32 vmlinuz
grub> linux (cd0)/isolinux/vmlinuz
grub> initrd (cd0)/isolinux/initrd.img
grub> boot
现在 Linux® 内核就加载完毕了,可以启动客户机:
# bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img \
-s 4:0,ahci-cd,./somelinux.iso -l com1,stdio -c 4 -m 1024M linuxguest
系统将会引导进入并启动安装器。在虚拟机中完成系统安装之后,重新启动虚拟机。bhyve 会在这时退出。请先销毁这个虚拟机实例,然后重新启动:
# bhyvectl --destroy --vm=linuxguest
现在客户机可以直接从磁盘镜像中启动了。首先加载内核:
# grub-bhyve -m device.map -r hd0,msdos1 -M 1024M linuxguest
grub> ls
(hd0) (hd0,msdos2) (hd0,msdos1) (cd0) (cd0,msdos1) (host)
(lvm/VolGroup-lv_swap) (lvm/VolGroup-lv_root)
grub> ls (hd0,msdos1)/
lost+found/ grub/ efi/ System.map-2.6.32-431.el6.x86_64 config-2.6.32-431.el6.x
86_64 symvers-2.6.32-431.el6.x86_64.gz vmlinuz-2.6.32-431.el6.x86_64
initramfs-2.6.32-431.el6.x86_64.img
grub> linux (hd0,msdos1)/vmlinuz-2.6.32-431.el6.x86_64 root=/dev/mapper/VolGroup-lv_root
grub> initrd (hd0,msdos1)/initramfs-2.6.32-431.el6.x86_64.img
grub> boot
引导进入虚拟机:
# bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 \
-s 3:0,virtio-blk,./linux.img -l com1,stdio -c 4 -m 1024M linuxguest
虚拟机中的 Linux® 将会启动并提示你登录。当你不再使用虚拟机时,重新启动虚拟机来退出 bhyve,并销毁虚拟机实例:
# bhyvectl --destroy --vm=linuxguest
24.6.4.使用 UEFI 固件引导 bhyve 虚拟机¶
除了 bhyveload 和 grub-bhyve,bhyve 虚拟机管理器还可使用 UEFI 用户空间固件来引导虚拟机。这可以兼容其他引导器不支持的客户机操作系统。
要利用 bhyve 的 UEFI 支持,首先要生成 UEFI 固件镜像。你可以通过 port 或软件包安装 sysutils/bhyve-firmware 来实现。
准备好固件之后,向 bhyve 命令添加标识 -l bootrom,/path/to/firmware
,例如:
# bhyve -AHP -s 0:0,hostbridge -s 1:0,lpc \
-s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,./disk.img \
-s 4:0,ahci-cd,./install.iso -c 4 -m 1024M \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
guest
sysutils/bhyve-firmware 还包含了启用 CSM 的固件,若要在 legacy BIOS 模式中启动不支持 UEFI 的客户机,请这样运行:
# bhyve -AHP -s 0:0,hostbridge -s 1:0,lpc \
-s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,./disk.img \
-s 4:0,ahci-cd,./install.iso -c 4 -m 1024M \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CSM.fd \
guest
24.6.5.为客户机设置图形化 UEFI 帧缓冲¶
UEFI 固件支持对主要使用图形化界面的客户机操作系统格外有用,例如 Microsoft Windows®。
对 UEFI-GOP framebuffer 的支持也可以用参数 -s 29,fbuf,tcp=0.0.0.0:5900
来启用。帧缓冲的分辨率可以通过如 w=800
h=600
来设置。bhyve 也可以通过添加 wait
来等待 VNC 连接,之后再引导进入客户机。framebuffer 可以从宿主机或者 VNC 协议的网络连接访问。此外,可以添加 -s 30,xhci,tablet
来实现与宿主机之间精确的鼠标同步。
最后的 bhyve 命令可能类似这样:
# bhyve -AHP -s 0:0,hostbridge -s 31:0,lpc \
-s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,./disk.img \
-s 4:0,ahci-cd,./install.iso -c 4 -m 1024M \
-s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \
-s 30,xhci,tablet \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
guest
注意,在模拟 BIOS 模式下,当控制从固件移交到宿主机操作系统后,帧缓冲会停止接收更新。
24.6.6.在 bhyve 客户机中使用 ZFS¶
如果在宿主机上可以使用 ZFS,在客户机上使用 ZFS 卷取代磁盘镜像可以显著提高性能。你可以这样新建一个 ZFS 卷:
# zfs create -V16G -o volmode=dev zroot/linuxdisk0
启动虚拟机时,指定 ZFS 卷作为磁盘驱动器:
# bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s3:0,virtio-blk,/dev/zvol/zroot/linuxdisk0 \
-l com1,stdio -c 4 -m 1024M linuxguest
24.6.7.虚拟机控制台¶
你可以使用类似于 sysutils/tmux 或者 sysutils/screen 这样的管理工具将 bhyve 控制台封装在一个会话中用来连接和断开控制台,这将带来一些好处。你还可以将一个空的调制解调器作为 bhyve 的控制台,然后使用 cu
来访问。若要这样做,请加载 nmdm 内核模块,然后将 -l com1,stdio
替换为 -l com1,/dev/nmdm0A
。设备 /dev/nmdm 会自动按需创建并组成一对,对应着空的调制解调器的两端(/dev/nmdm0A 和 /dev/nmdm0B)。查阅 nmdm(4) 获取更多信息。
# kldload nmdm
# bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img \
-l com1,/dev/nmdm0A -c 4 -m 1024M linuxguest
# cu -l /dev/nmdm0B
Connected
Ubuntu 13.10 handbook ttyS0
handbook login:
24.6.8.管理虚拟机¶
对于每个虚拟机,在 /dev/vmm 下都会创建一个设备节点。这使得管理员很容易就能看到运行中的虚拟机列表:
# ls -al /dev/vmm
total 1
dr-xr-xr-x 2 root wheel 512 Mar 17 12:19 ./
dr-xr-xr-x 14 root wheel 512 Mar 17 06:38 ../
crw------- 1 root wheel 0x1a2 Mar 17 12:20 guestname
crw------- 1 root wheel 0x19f Mar 17 12:19 linuxguest
crw------- 1 root wheel 0x1a1 Mar 17 12:19 otherguest
通过 bhyvectl
可以销毁指定的虚拟机:
# bhyvectl --destroy --vm=guestname
24.6.9.持久化配置¶
要配置系统在启动时运行 bhyve 虚拟机,请进行如下配置:
/etc/sysctl.conf
net.link.tap.up_on_open=1
/etc/rc.conf
cloned_interfaces="bridge0 tap0" ifconfig_bridge0="addm igb0 addm tap0" kld_list="nmdm vmm"