24.6.使用 FreeBSD 上的 QEMU 虚拟化
最后更新于
最后更新于
是一款通用的机器仿真和虚拟化工具,完全开源,由一个庞大且活跃的社区开发,支持 FreeBSD、OpenBSD 和 NetBSD 以及其他操作系统。
根据 :
QEMU 可以通过多种方式使用。最常见的是系统仿真模式,在该模式下,QEMU 提供了一个完整机器的虚拟模型(包括 CPU、内存和仿真设备),用于运行虚拟机操作系统。在这种模式下,CPU 可以完全仿真,也可以与如 KVM
、Xen
或 Hypervisor.Framework
等虚拟化管理程序合作,使虚拟机直接在宿主 CPU 上运行。
第二种使用方式是用户模式仿真,在该模式下,QEMU 可以在一种 CPU 上启动为另一种 CPU 编译的进程。在此模式下,CPU 始终为仿真状态。
QEMU 还提供了多个独立的命令行工具,例如 磁盘映像工具,允许用户创建、转换和修改磁盘映像。
QEMU 可以仿真多种体系结构,包括 Arm™
、i386
、x86_64
、MIPS™
、s390X
、SPARC™
(Sparc™ 和 Sparc64™)等。有关 QEMU 系统仿真目标的完整列表,请参阅 ,该列表会定期更新。
本节介绍了如何在 FreeBSD 上使用 QEMU 进行系统仿真和用户模式仿真,并提供了 QEMU 命令和命令行工具的使用示例。
QEMU 可以作为 FreeBSD 的一款软件包或在 中作为 Port 安装。推荐的安装方法是使用软件包构建,因为它包含了大多数用户需要的合理选项和默认设置。
安装软件包时会包含一些依赖项。安装完成后,创建一个指向宿主版本的 QEMU 链接,通常情况下如果宿主系统是 Intel™ 或 AMD™ 64 位系统,命令为:
作为非 root 用户运行以下命令来测试安装:
这将打开一个窗口,QEMU 会尝试从硬盘、软盘、DVD/CD 和 PXE 启动。由于尚未设置任何启动映像,因此命令会产生一些错误并以 "No bootable device" 结束,如 所示。不过,这表明 QEMU 软件已正确安装。
图 1. 没有可引导映像的 QEMU
注意
按照以下步骤创建两个名为“left”和“right”的虚拟机。大多数命令可以在没有 root 权限的情况下执行。
创建一个测试环境来与 QEMU 一起使用:
SCRIPTS 目录用于存放启动脚本和实用工具。ISO 目录用于存放客户机 ISO 启动映像。VM 目录是虚拟机映像(VMs
)的存放位置。
将最新的 FreeBSD 下载到 ~/QEMU/ISO 目录中:
下载完成后,创建一个简短的链接。该简短链接将在下面的启动脚本中使用。
QEMU raw
格式旨在提供最佳性能。该格式简单且没有开销,特别适用于高性能或高吞吐量的场景。此格式适用于对性能要求最大化且不需要额外功能(如快照)的情况。以下脚本中使用了此格式来创建 “left” 虚拟机的磁盘映像。
另一种格式是 qcow2
,它使用 QEMU 的“写时复制”技术来管理磁盘空间。这种技术不需要完整的 15G 磁盘,而是直接由虚拟机管理一个简版磁盘,随着虚拟机写入,磁盘大小会动态增长。此格式支持快照、压缩和加密。此格式适用于开发、测试及需要这些高级功能的场景。下面的 “right” 虚拟机脚本使用了此格式。
要查看实际文件大小,可以使用:
使用以下命令为两个虚拟机配置网络。在此示例中,宿主网络接口是 em0
。如果有必要,请修改为宿主系统的接口。每次宿主机重启后必须执行这些命令,以便让 QEMU 客户机虚拟机能够进行通信。
切换到 ~/QEMU/SCRIPTS 目录,使用以下脚本启动第一个虚拟机 “left”。该脚本使用了 QEMU 的原始磁盘格式。
技巧
将上述内容保存到一个文件中(例如
left.sh
),并只需运行:%/bin/sh left.sh
图 2. FreeBSD 启动加载菜单
技巧
图 3. 当 QEMU 抓取鼠标时
注意
在 FreeBSD 上,初始的 QEMU 安装可能会稍慢。这是因为模拟器在第一次使用磁盘时会写入文件系统格式和元数据。随后的操作通常会更快。
安装过程中有几个需要注意的要点:
选择使用 UFS 作为文件系统。ZFS 在小内存的环境下性能不佳。
网络配置使用 DHCP。如果本地局域网支持,也可以配置 IPv6。
在添加默认用户时,请确保该用户是 wheel 组的成员。
安装完成后,虚拟机将重启并进入新安装的 FreeBSD 映像。
以 root
用户登录并按以下方式更新系统:
注意
安装成功后,QEMU 将引导已安装的操作系统,而不是安装程序。
注意
至此,"left" 虚拟机的安装已完成。
要安装 "right" 虚拟机,请运行以下脚本。此脚本包含了 tap1、qcow2
格式、映像文件名、MAC 地址和终端窗口名的修改。如果需要,可以按照上述说明添加 "-runas" 参数。
安装完成后,“left”和“right”虚拟机可以相互通信,并与宿主进行通信。如果宿主机上有严格的防火墙规则,考虑添加或修改规则以允许桥接和 tap 设备之间的通信。
本节演示了 XFCE 桌面环境的使用。
安装完成后,作为常规用户登录,然后输入:
图 4. 两个 QEMU 虚拟机
技巧
为虚拟系统添加更多内存可能会加速图形用户界面。
在这里,“left”虚拟机已经安装了 X Window
系统,而“right”虚拟机仍处于文本模式。
QEMU 窗口作为一个完整的 FreeBSD 控制台,能够像裸机系统一样运行多个虚拟终端。
图 5. 在 QEMU 窗口中切换到另一个虚拟控制台
技巧
当前主机桌面管理器或窗口管理器可能已经为 Alt+F1、Alt+**F2 键序列设置了其他功能。如果是这样,请尝试输入 Ctl+Alt+F1、Ctl+Alt+F2,或其他类似的键组合。查看窗口管理器或桌面管理器文档以了解详细信息。
图 6. 使用视图菜单中的 Zoom to Fit
选项
在 View
菜单中,还可以看到以下选项:
cirrus-vga
、serial0
和 parallel0
选项。这些选项允许切换输入/输出到选定设备。
QEMU 窗口中的 Machine
菜单提供了对虚拟机的四种控制:
Pause
可暂停 QEMU 虚拟机。这可能对冻结快速滚动的窗口有帮助。
Reset
会立即将虚拟机重置为冷启动状态。与实际机器一样,除非绝对必要,否则不建议使用此选项。
Power Down
模拟 ACPI 关闭信号,操作系统将执行优雅的关闭过程。
Quit
会立即关闭虚拟机电源 — 同样,不建议除非必要时使用此选项。
为了实现串行控制台,需要在运行 FreeBSD 的虚拟机中插入以下内容:
将此行添加到 /boot/loader.conf 文件中,以启用 FreeBSD 串行控制台的使用。
以下更新后的配置演示了如何在虚拟机上实现串行控制台。运行脚本以启动虚拟机。
图 7. 通过 TCP 启用串行端口
需要注意的是,这种通过 TCP 的串行重定向是在虚拟机之外进行的。它不与虚拟机中的任何网络进行交互,因此不受任何防火墙规则的限制。可以将其视为连接到实际机器的 RS-232 或 USB 端口的傻终端。
注意
待 /boot.loader.conf 文件已更新以允许串行控制台,虚拟机将在每次启动时尝试从串行端口启动。确保如上所示启用串行端口,或者更新 /boot/loader.conf 文件以不要求使用串行控制台。
QEMU 还支持在与主机 CPU 架构不同的体系结构上运行预编译的应用程序。例如,可以在 x86_64 主机上运行 Sparc64 架构的操作系统。下一节将展示这一过程。
设置与主机架构不同的新虚拟机涉及以下几个步骤:
获取将在虚拟机上运行的软件
为虚拟机创建一个新的磁盘镜像
设置一个新 QEMU 脚本,指定新的架构
执行安装
以下过程使用了 OpenBSD 6.8 SPARC64 软件作为本次 QEMU 用户模式仿真练习的示例。
技巧
并非所有版本的 OpenBSD Sparc64 都能在 QEMU 上运行。已知 OpenBSD 版本 6.8 可用,因此作为本节示例。
从 OpenBSD 存档中下载 OpenBSD 6.8 Sparc64。 在 OpenBSD 下载站点上,仅保留最新版本,需要访问存档以获取过去的版本。
为 Sparc64 虚拟机创建新的磁盘镜像,这与上面的 "right" 虚拟机创建方法类似。在本例中使用 QEMU 的 qcow2 格式:
使用以下脚本设置新的 Sparc64 架构。与上面的示例一样,运行该脚本,然后启动一个新的会话并通过 telnet
连接到 localhost 上指定的端口:
注意以下几点:
-boot d
选项使 QEMU 从设置为 -cdrom ../ISO/install68.iso
的 QEMU CDROM 设备启动。
该脚本设置了 -nographic
选项,意味着只有串行端口 I/O,没有图形界面。
图 8. QEMU 在用户模式仿真中从 CDROM 启动 OpenBSD 6.8 Sparc64
安装完成后,修改脚本并将启动参数更改为 -boot c
。这将指示 QEMU 从提供的硬盘启动,而不是 CDROM。
安装后的系统可以像其他虚拟机一样使用。然而,虚拟机的底层架构是 Sparc64,而非 x86_64。
技巧
如果系统在 OpenBios 控制台提示
0 >
时停止,请输入power-off
来退出系统。
图 9. 在用户模式仿真中从 CDROM 启动 QEMU
通过使用监控器,可以:
动态地移除或插入设备,包括磁盘、网络接口、CD-ROM 或软盘
冻结/解冻虚拟机,并将其状态保存或恢复到磁盘文件中
收集有关虚拟机和设备状态的信息
实时更改设备设置
以及许多其他操作。
监控器的最常见用途是检查虚拟机的状态,并添加、删除或更改设备。一些操作,如迁移,仅在支持的虚拟化加速器(如 KVM、Xen 等)下可用,在 FreeBSD 主机上不受支持。
在使用图形桌面环境时,最简单的使用 QEMU 监控器的方法是启动 QEMU 时使用 -monitor stdio
选项。
图 10. QEMU 监控器提示符和“stop”命令
图中还显示了在 FreeBSD 启动序列中使用 stop
命令冻结系统。系统将保持冻结状态,直到在监控器中输入 cont
命令。
要向运行中的虚拟机添加新磁盘,首先需要准备磁盘,如下所示:
请注意,如果需要在虚拟机重启后使用新磁盘,必须将其添加到启动脚本中。
图 11. 使用 QEMU 监控器命令添加新磁盘
QEMU 文档在使用术语 快照 时描述了几个类似的概念。命令行上有 -snapshot
选项,它指的是使用一个磁盘或磁盘的一部分来包含设备的副本。然后是监控器命令 snapshot_blkdev
和 snapshot_blkdev_internal
,它们描述了实际的复制块设备的操作。最后,还有监控器命令 savevm
、loadvm
和 delvm
,它们指的是创建并保存、加载或删除整个虚拟机的副本。结合后者,监控器的 info snapshots
命令列出了最近的快照详情。
本节将重点介绍创建、保存和加载完整的虚拟机镜像,并使用 快照 这一术语。
首先,从头开始重新创建“左”虚拟机,这次使用 qcow2
格式。
安装完成后,重新启动虚拟机,这次使用 -monitor stdio
选项来启用监控器。
为了演示快照,可以使用以下步骤:
从头安装 FreeBSD
准备环境并使用 savevm
监控器命令创建快照
安装几个软件包
关闭系统
重新启动一个裸 QEMU 实例,并使用监控器命令 loadvm
恢复虚拟机
观察恢复后的虚拟机没有安装任何软件包
图 12. 第一次快照之前的 QEMU 虚拟机
要生成快照,请在监控器中输入 savevm
。确保为其指定标签(例如 original_install
)。
图 13. 使用监控器命令进行快照
重新启动系统,在 FreeBSD 启动之前,切换到监控器并输入 stop
。虚拟机将停止。
输入 loadvm
和之前使用的标签(此处为 original_install
)。
立即,虚拟机屏幕将切换到执行 savevm
命令时的准确时刻。请注意,虚拟机仍然处于停止状态。
输入 cont
启动虚拟机,切换到 ttyv1
上的编辑会话,并在键盘上输入一个字母。编辑器仍然处于插入模式,应该相应地响应。快照时运行的任何其他程序应该没有受到影响。
上述步骤展示了如何创建快照、修改系统,然后通过恢复之前的快照来“回滚”。
QEMU 支持创建虚拟 USB 设备,这些设备由映像文件提供支持。它们是虚拟 USB 设备,可以像真实 USB 设备一样进行分区、格式化、挂载和使用。
当系统启动时,FreeBSD 会识别到一个 USB 集线器,添加附加的 USB 设备,并将其分配为 da0
,如图 15 所示。
图 15. QEMU 创建的 USB 集线器和大容量存储设备
QEMU USB 直通支持在 9.0.1 版本(2024 年夏季)中列为实验性功能。以下步骤展示了如何使用挂载在主机上的 USB 闪存驱动器。
更多信息和示例,请参见:
info usbhost
显示主机系统上所有 USB 设备的信息。找到所需的 USB 设备并记下该行中的两个十六进制值。(在下面的示例中,主机 USB 设备是 Memorex Mini,vendorid 为 0718,productid 为 0619。)在下面的 device_add
步骤中使用 info usbhost
命令显示的两个值。
device_add
将 USB 设备添加到虚拟机。
图 16. QEMU 监视器命令访问主机上的 USB 设备
如前所述,device_add
完成后,FreeBSD 内核会识别到新的 USB 设备,如图下部分所示。
图 17. 通过直通使用主机的 USB 设备
如上所述,QEMU 支持多种不同的虚拟化加速器。
在 Linux 上支持 64 位 Arm、MIPS、PPC、RISC-V、s390x 和 x86 的 KVM
在 Linux 上作为 dom0 支持 Arm、x86 的 Xen
在 MacOS 上支持 x86 和 Arm(仅 64 位)的 Hypervisor Framework (hvf)
在 Windows 上支持 x86 的 Windows Hypervisor Platform (whpx)
在 NetBSD 上支持 x86 的 NetBSD Virtual Machine Monitor (nvmm)
在 Linux 和其他 POSIX 系统、Windows、MacOS 上支持 Arm、x86、Loongarch64、MIPS、PPC、s390x 和 Sparc64 的 Tiny Code Generator (tcg)
本节中的所有示例都使用了 Tiny Code Generator (tcg)
加速器,因为这是当前在 FreeBSD 上支持的唯一加速器。
QEMU 处于非常活跃的开发状态,特性和命令选项可能会在不同版本之间发生变化。本节提供了使用 QEMU 版本 9.0.1(2024 年夏季)开发的示例。若有疑问,请始终查阅 ,特别是 页面,该页面包含支持的构建平台、仿真、已弃用功能和已移除功能的链接。
切换到虚拟机存放位置(~/QEMU/VM)。运行 来为 “left” 虚拟机创建磁盘映像:
再次运行 来为 “right” 虚拟机创建一个 qcow2
格式的磁盘映像:
上述命令创建了两个 设备(tap0
、tap1
)和一个 设备(bridge0
)。接着,它们将 tap
设备和本地宿主接口(em0
)添加到桥接中,并设置了两个 项目,允许普通用户打开 tap 设备。这些命令使虚拟机能够与宿主的网络栈进行通信。
QEMU 将在一个单独的窗口中启动虚拟机,并按 中所示引导 FreeBSD ISO。所有命令选项,如 -cpu
和 -boot
,均在 QEMU 的手册页 中有详细描述。
如果在 QEMU 控制台窗口中点击鼠标,QEMU 将“抓取”鼠标,如 所示。按 Ctl+Alt+G 可以释放鼠标。
QEMU 支持 -runas
选项。为了增加安全性,可以在上述脚本中包括 "-runas your_user_name" 选项。详情请参见 。
再次以 root
用户登录,添加所需的任何软件包。若要在客户机中使用 X Window 系统,请参阅下文的“使用 X Window 系统”部分。
描述了如何设置 X Window
系统。请参考该指南进行初始的 X Window
设置,然后查阅 以了解如何设置完整的桌面环境。
XFCE4 窗口管理器将启动并呈现一款功能齐全的图形桌面,如 所示。首次启动时,可能需要一分钟才能显示桌面。有关使用详细信息,请参阅 。
要切换到另一个虚拟控制台,单击 QEMU 窗口并输入 Alt+**F2 或 Alt+F3。FreeBSD 应该会切换到另一个虚拟控制台。 显示了 "left" 虚拟机在 ttyv3
上显示虚拟控制台的情况。
QEMU 窗口的另一个功能是 View
菜单和缩放控制。最有用的是 Zoom to Fit
。当点击此菜单项时,可以通过点击窗口角部控制并调整窗口大小来调整 QEMU 窗口的大小。 显示了在图形模式下调整“left”窗口大小的效果。
在 中,串行端口被重定向到主机系统的 TCP 端口,并且 QEMU 监视器等待(wait=on
)直到在指定的 localhost 端口发生 连接。当收到来自另一个会话的连接时,FreeBSD 系统开始启动并查找 /boot/loader.conf 中的控制台指令。通过设置 "console=comconsole",FreeBSD 在串行端口上启动一个控制台会话。QEMU 监视器会检测到这一点,并将该串行端口的字符 I/O 导向主机上的 telnet 会话。系统启动完成后,登录提示将在串行端口(ttyu0
)和控制台(ttyv0
)上启用。
在串行控制台上,如果调整了窗口大小,可以执行 来更新终端大小。
有时可能需要(甚至必须)停止将 syslog 消息发送到控制台(包括 QEMU 控制台和串行端口)。有关将控制台消息重定向到其他位置的详细信息,请参考 。
如前所述,telnet
服务器选项设置为等待在端口 4410 上接收连接。启动另一个会话并使用 连接到 localhost 上的 4410 端口。
本例中网络未通过 / 组合设置。这里使用了 QEMU 网络的另一种方法,称为“串行线互联网协议”(SLIRP),有时也称为“用户模式网络”。有关该方法及其他 QEMU 网络方法的文档,请参见
如果一切设置正确,系统将启动,如 所示。
显示了登录已安装系统的 root 用户并运行 。
用于控制正在运行的 QEMU 模拟器(虚拟机)。
这将在终端窗口中生成一个新的提示符 (qemu)
,如 所示。
显示了向虚拟机添加新磁盘所需的监控器命令序列。待使用监控器中的 device_add
命令添加了设备,它将在 FreeBSD 系统控制台中显示(图中的下半部分)。此时可以根据需要配置磁盘。
在“准备环境”步骤中,在一个独立的虚拟控制台(ttyv1)中启动一个 编辑会话,模拟用户活动。如果需要,可以启动其他程序。快照应该记录在创建快照时所有正在运行的应用程序的状态。
显示了全新安装的 FreeBSD 系统,尚未安装任何软件包,并且在 ttyv1 上单独显示了编辑会话。当前, 编辑器处于 insert
模式,打字员正在输入“broadcast”一词。
接下来,在主控制台窗口中安装一个软件包,例如没有依赖关系的 。完成后,重新进入监控器并创建另一个快照(snap1_pkg+zip
)。
显示了上述命令的结果以及 info snapshots
命令的输出。
默认情况下,QEMU 将快照数据存储在与镜像相同的文件中。使用 查看快照列表,如下所示,见 。
图 14. 使用 检查快照
此配置包括一个 -drive
规范,指定了 id=usbstick
、raw 格式和一个映像文件(必须使用 创建)。下一行包含 -device usb-ehci
规范,指定一个 USB EHCI 控制器,并指定 id=ehci
。最后,-device usb-storage
规范将上述驱动与 EHCI USB 总线连接起来。
该设备已准备好,可以使用 进行分区,并使用 进行格式化。由于 USB 设备由 创建的文件提供支持,写入设备的数据会在重启后保留。
的上部分显示了 QEMU 监视器命令:
在 中,展示了如何使用新设备。
如果 USB 设备格式化为 FAT16 或 FAT32 文件系统,则可以使用 将其挂载为 MS-DOS™ 文件系统,如示例所示。然后将 /etc/hosts
文件复制到新挂载的驱动器上,并对文件进行校验和验证其完整性。然后使用 卸载设备。
如果 USB 设备格式化为 NTFS,则需要安装 fusefs-ntfs
包并使用 访问该设备:
根据实际硬件修改上述设备标识符。有关 NTFS 文件系统操作的更多信息,请参阅 。
QEMU 支持的 包括: