21.7. 在 FreeBSD 上使用 bhyve 虚拟机

从 10.0-RELEASE 开始,bhyve 成为了 FreeBSD 基础系统的一部分。bhyve 的客户机支持 FreeBSD、NetBSD、OpenBSD 和 Linux 等多种操作系统。默认情况 FreeBSD 提供串行控制台,不提供图形控制台。具有虚拟化运算卸载(offload)功能的新 CPU 可用于避免转换指令集和手动管理映射。

bhyve要求处理器支持Intel®扩展页表(EPT)或AMD®快速虚拟化索引(RVI)或嵌套页表(NPT)。托管 Linux® 虚拟机或 FreeBSD 虚拟机,并使用一个以上的 vCPU,需要 CPU支持 VMX 非限制模式支持 (UG)。大多数较新的处理器,特别是 Intel® Core™ i3/i5/i7 和 Intel® Xeon™ E3/E5/E7,都支持这些功能。UG支持是通过英特尔的Westmere微架构推出的。 RVI出现在第三代及以后的AMD Opteron™(巴塞罗那)处理器上。判断处理器是否支持bhyve的最简单方法是运行dmesg或在/var/run/dmesg. boot中查找AMD®处理器的Features2行中的POPCNT处理器特性标志,或者Intel®处理器的EPTVT-x行中的UG

21.7.1. 准备宿主机(Host)

在 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

21.7.2. 创建 FreeBSD 客户机

创建虚拟机的磁盘镜像文件,并设置好名字和大小:

# truncate -s 16G guest.img

下载 FreeBSD 的安装镜像:

# fetch ftp://ftp.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/10.3/FreeBSD-10.3-RELEASE-amd64-bootonly.iso
FreeBSD-10.3-RELEASE-amd64-bootonly.iso       100% of  230 MB  570 kBps 06m17s

FreeBSD 附带了一个示例脚本,用于在bhyve中运行虚拟机。脚本将启动虚拟机并在循环中运行它,因此,当它崩溃时,它将自动重启。该脚本由多个参数用于配置虚拟机:-c 用于设置 CPU 核数,-m 设置虚拟机内存,-t 定义要使用的水龙头设备,-d 设置要使用的磁盘镜像文件,-i 让虚拟机从 CD 启动而不是磁盘镜像;-l 设置要使用的CD镜像位置。最后一个参数是虚拟机的名称,用于跟踪正在运行的虚拟机。本示例在安装模式下启动虚拟机:

# sh /usr/share/examples/bhyve/vmrun.sh -c 1 -m 1024M -t tap0 -d guest.img -i -I FreeBSD-10.3-RELEASE-amd64-bootonly.iso guestname

虚拟机将启动并启动安装程序。在虚拟机中安装系统后, 当系统询问在安装结束时进入shell 时, 请选择Yes

重启虚拟机,在重启虚拟机的过程中bhyve将退出,vmrun.sh将自动重启bhyve。当这些发生时,从 bootloader 菜单中选择重启来跳出此循环。现在客户机可以从虚拟磁盘启动了:

# sh /usr/share/examples/bhyve/vmrun.sh -c 4 -m 1024M -t tap0 -d guest.img guestname

21.7.3. 在客户机上安装基于Linux®的操作系统

为了在客户机中启动非 FreeBSD 操作系统,请先安装sysutils/grub2-bhyve

然后为客户机创建虚拟磁盘:

# truncate -s 16G linux.img

使用bhyve启动虚拟机需要两步。首先必须加载内核,然后才能启动 Guest。sysutils/grub2 bhyve加载了Linux®的内核。创建grub将用于将虚拟设备映射到主机系统上的文件的device.map

(hd0) ./linux.img
(cd0) ./somelinux.iso

使用sysutils/grub2-bhyve从 ISO 镜像中加载 Linux® 内核:

# grub-bhyve -m device.map -r cd0 -M 1024M linuxguest

这将会启动 grub。如果安装媒体中有grub.cfg,将会显示启动菜单,若没有则需手动查找并加载vmlinuzinitrd

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

21.7.4. 使用 UEFI 启动 bhyve 虚拟机

除了bhyveloadgrub-bhyvebhyve 也可以使用 UEFI 用户空间固件启动虚拟机。这可能只支持部分操作系统。

要在bhyve上启动 UEFI 支持,首先获取 UEFI 固件镜像。这可以通过安装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的固件,用以支持BIOS模式:

# 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

21.7.5. 适用于bhyve客户机的UEFI图形帧缓冲器

UEFI固件支持对于主要的图形来宾操作系统(如Microsoft Windows®)特别有用。

也可以使用-s 29,fbuf,tcp=0.0.0.0:5900标志启用对UEFI-GOP帧缓冲区的支持。帧缓冲区分辨率可以配置为w=800h=600,并且可以通过添加wait来指示bhyve在引导来宾系统之前等待VNC连接。帧缓冲区可以通过 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 仿真模式下,一旦控制权从固件传递到客户机作系统,帧缓冲器将停止接收更新。

21.7.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

21.7.7. 虚拟机的终端

建议将bhyve控制台包装在会话管理工具(如sysutils/tmuxsysutils/screen)中,防止终端关闭时程序自动退出。也可以设置bhyve的控制台为一个 null modem,可以使用cu访问。为此,请加载nmdm内核模块并将-l com1,stdio 替换为-l com1,/dev/nmdm0A/dev/nmdm设备根据需要自动创建,其中每个设备是一对,对应于 null modem 电缆的两端 (/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:

21.7.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

使用/dev/vmm删除虚拟机:

# bhyvectl --destroy --vm=guestname

21.7.9. 持久化配置

为了能让 bhyve 虚拟机在宿主机启动时启动,请将以下行添加到指定文件中:

  1. /etc/sysctl.conf

    net.link.tap.up_on_open=1
  2. /etc/rc.conf

    cloned_interfaces="bridge0 tap0"
    ifconfig_bridge0="addm igb0 addm tap0"
    kld_list="nmdm vmm"

本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.