前言
当想要尝试新的发行版,或者是遇到一些只能在 Windows 系统上运行的软件,我会选择在虚拟机中运行,能够自己随便折腾而不影响到宿主系统。在之前我使用的虚拟机管理软件是 VirtualBox,这是一个开源免费的,支持多种平台的虚拟机管理软件。但我在使用 VirtualBox 过程中也渐渐有些不爽,首先是要想让虚拟机与宿主机有较好的交互,比如文件共享,自动切换分辨率之类的,就需要在虚拟机中安装扩展包,但是在一些 Linux 发行版上安装扩展包后经常出一些玄学问题;还有就是性能比较差,图形 3D 加速配置什么的也比较迷。
就在最近我发现了另一个虚拟机管理软件,叫做 virt-manager,这个软件利用了 Linux 内核 KVM 功能和 virtio 半虚拟化技术,可以让虚拟机有较少的性能损失,运行也更流畅,当然这些功能需要 Linux 内核支持,其他系统比如 Windows 自然没办法使用这个软件(但是理论上在 Windows 上通过 WSL 安装并运行 virt-manager 应该也是可行的,我没有试过,感兴趣的可以尝试一下)。virt-manager 并不是一个完整的虚拟机管理软件,而是 Libvirt 的一个图形化前端,安装时除了要安装 virt-manager,也需要安装并配置好 Libvirt,可能是这个软件相对较新,网上文档比较少,我搜索到的很多 virt-manager 的安装教程都各不相同,最后我发现 ArchWiki 上的这个教程相对比较可靠,但也有些问题。所以我在这里记录一下我的安装过程以及一些使用心得。
软件安装
本节的软件安装是在 Arch Linux 上进行的,在其他的发行版上包管理器命令和软件包名可能不同,请注意。
需要安装的软件包有 virt-manager 软件本体,qemu-desktop 用来支持 KVM/QEMU,dnsmasq 用来为虚拟机分配网络地址,我看到有些教程说要安装 iptables 和 ebtables 来为虚拟机配置网络,不过 ebtables 的功能已经被集成进了 nftables,而且 iptables 已经停止支持了,所以只需安装 iptables-nft 就够了。
接下来要对 Libvirt 进行一些配置,网上的大部分教程推荐启用 libvirtd.service 这个服务,但在 ArchWiki 的教程中提到,如果只用 QEMU 的话,其实是不需要启用这个服务的,使用 LXC 才需要启用服务。我自己经过测试,发现如果只用 QEMU/KVM 用户会话,是不需要启用服务的,而如果使用的是默认的 QEMU/KVM 会话,是需要启用服务的,否则会连接失败。
要想让非 root 用户使用 virt-manager,还需要配置相关的权限,首先编辑 /etc/libvirt/libvirtd.conf
,找到以下两行,如果有井号注释就取消注释,把 unix_sock_group
设置为 libvirt,把 unix_sock_rw_perms
设置为 0770:
unix_sock_group = 'libvirt'
unix_sock_rw_perms = '0770'
之后将自己的用户加入 libvirt 的用户组:
sudo groupadd libvirt
sudo usermod -a -G libvirt username
然后编辑 /etc/libvirt/qemu.conf
,找到 user = "libvirt-qemu"
和 group = "libvirt-qemu"
这两行,取消注释,然后将引号中的内容改为自己的用户名:
# Some examples of valid values are:
#
# user = "qemu" # A user named "qemu"
# user = "+0" # Super user (uid=0)
# user = "100" # A user named "100" or a user with uid=100
#
user = "username"
# The group for QEMU processes run by the system instance. It can be
# specified in a similar way to user.
group = "username"
首次启动
首次启动 virt-manager 时,软件会默认使用 root 用户的 QEMU/KVM 会话,如果没有启用 libvirtd.service 服务,还会提示连接失败,而且默认的 QEMU/KVM 会话会将相关文件保存在根目录下,后期的管理也有些不方便,所以可以选择更改到普通用户的 QEMU 连接。点击右上角的文件
>添加连接
,虚拟机管理程序选择为 QEMU/KVM 用户会话
,点击连接
即可,这样相关的文件会保存到用户目录的 ~/.local/share/libvirt/
下面,后期管理相对方便一些,不过值得注意的是,用户会话下一些功能会受到限制,但对于普通用户也完全够用了。如果想的话,也可以选择删掉默认的 QEMU 连接。
创建虚拟机
使用 virt-manager 创建新虚拟机也相对比较简单,在软件主界面,点击右上角的加号即可添加虚拟机,这里我用包含非自由固件的 Debian11 网络安装 iso 为例,软件会自动检测系统的类型,而且它不是用文件名检测的,包含非自由固件的 Debian11 下载后的 iso 默认文件名并不包含 Debian 关键字,但软件还是检测到了是 Debian11,当然如果检测错误也可以手动选择系统类型,之后按照正常的步骤一直下一步,除了 CPU、内存和虚拟磁盘大小,其他一般无需过多配置,如果想对虚拟机进行进一步配置,也可以在最后一步勾选 在安装前自定义配置
,或者在系统安装好后再进行配置。不过需要注意的是,Libvirt 默认用的虚拟磁盘格式为 .qcow2
,和 VirtualBox 用的虚拟磁盘格式并不通用,而且 qcow 格式的虚拟磁盘似乎也并不支持空间动态分配,如果分配了 40G 的虚拟磁盘,那么就会占用 40G 空间,即使虚拟磁盘是空的。
管理虚拟机
在 virt-manager 的主界面,选择已经安装好的虚拟机,右键选择打开就可以打开虚拟机的控制台,左上角从左到右分别是「显示图形控制台」、「显示虚拟硬件详情」还有几个电源选项,右上角是全屏,点击「显示虚拟硬件详情」就可以查看虚拟机的虚拟硬件并进行配置了,在这里可以管理、添加和删除虚拟硬件。下面介绍一些我摸索出来的使用技巧。
虚拟显示器 3D 加速
如果是 Linux 系统的虚拟机,因为 Linux 内核已经对 virtio 有很好的驱动支持,所以 virt-manager 默认就会使用 virtio 来虚拟化显示设备,从而有更好的性能,但是 virt-manager 默认并没有为显示设备开启 3D 加速,所以在 Linux 虚拟机的图形界面会出现动画缺失、卡顿与撕裂,为了解决这个问题,需要手动开启 3D 加速。
首先在「显示虚拟硬件详情」界面,找到「显示协议」一项并选中,在右边的详情页面,类型「spice 服务器」不用修改,将监听类型修改为「无」,并在下方勾选「OpenGL」,不要忘了修改完要在右下方点击「apply」保存修改。
之后找到「显卡」一项并选中,在右边详情页面勾选「3D 加速」并保存修改。然后打开虚拟机就发现图形界面很流畅了。
virt-manager 在修改完虚拟硬件并保存前会检查配置文件是否有不兼容,显示协议中「OpenGL」没有勾选,显卡中就无法勾选「3D 加速」,而若不将监听类型修改为「无」就无法勾选「OpenGL」,所以操作一定要按顺序来,不然就会无法保存修改。
另外我发现 Linux 虚拟机开启了 virtio 3D 加速的话,在 tty 界面命令行滚动时会有撕裂,可能也是因为这个原因 virt-manager 默认没有开启 3D 加速吧,所以如果安装的 Linux 虚拟机不使用图形界面的话,还是不要开启 3D 加速比较好。
而 Windows 虚拟机就会复杂一些,因为 Windows 默认并没有 virtio 驱动支持,所以在创建 Windows 虚拟机时 virt-manager 默认会使用 QXL 显示驱动,虽然 QXL 也是一个性能损失相对较小的方案,但我个人使用下来觉得还是不如 virtio 显示驱动流畅。为了让 Windows 使用 virtio 显示驱动,需要为 Windows 虚拟机安装 virtio 驱动软件。
在网上搜索「virtio Windows driver」,我找到了 Proxmox VE 的这篇文档,文档中推荐使用 Fedora 社区提供的 virtio 驱动,可以在这里下载最新稳定版或这里下载最新的构建版本,下载后是一个 iso 文件。打开 Windows 虚拟机的「显示虚拟硬件详情」页面,找到「SATA CDROM」,没有就在右下角点击添加硬件新建一个,在右边的详情页面中,「源路径」处选择刚刚下载的 iso 文件。
启动进入 Windows 虚拟机,会看到有一个光驱设备,打开后,有两个 msi 可执行文件,64 位系统需要运行 virtio-win-gt-x64.msi
,一路下一步就可以安装上 virtio 驱动了。另外也可以选择运行 virtio-win-guest-tools.exe
来安装 QEMU Guest Agent 和 SPICE agent 来获得更好的远程桌面的体验。
之后的步骤就和上文差不多,显示协议里面将监听类型修改为「无」并勾选「OpenGL」,显卡里面将型号改为「virtio」并勾选上「3D 加速」,再次启动虚拟机,就可以使用了。
宿主机与虚拟机文件共享
在虚拟机的使用场景中,让虚拟机与宿主机共享文件是一个十分有用的功能,virt-manager,或者说 Libvirt 是通过 virtiofs 驱动来实现文件共享的,不过需要注意的是在 QEMU/KVM 用户会话模式是无法通过 virtiofs 来共享文件的,在 root 模式下才可以使用。
首先打开对应虚拟机的控制台,点击「显示虚拟硬件详情」,找到「内存」一项,在右边详情页勾选「Enable shared memory」并保存修改。
之后点击左下角添加硬件,选择「文件系统」,源路径选择宿主机上想要共享的文件夹,目标路径随便填上一个名字即可,比如这里我填的是「share」。
之后打开虚拟机,Linux 系统的话,运行:
sudo mount -t virtiofs share /mnt
就可以将共享文件夹挂载到虚拟机中的 /mnt/
路径,其中的「share」就是之前目标路径里填的名字。
Windows 虚拟机的话要更麻烦一些,我没有试过,但是看到有这个教程,感兴趣的可以参考一下。
其实,折腾了一圈,我最后发现,还是在宿主机上开一个 smb 共享 来的更为简单。
总结
Linux 内核的 KVM/QEMU 支持与 Libvirt 的虚拟机管理功能本身其实是为了服务器和专业用途而设计的,因此具备很强大的功能,但随之带来的是相对较高的配置难度和纯命令行的配置方法,对于普通用户的使用,还是有些不方便,因此诞生了很多图形化的软件尝试简化 Libvirt 的配置难度,除了本篇文章介绍的 virt-manager,类似的还有 GNOME Boxes,相对而言 GNOME Boxes 的使用要更简单一些,但支持的功能也会少一些。但即便如此,这类软件也很难做到像 VirtualBox 和 VMware 这类知名虚拟机管理软件接近开箱即用的体验和多平台支持,不过好处是更少的性能损失和更灵活的配置,这个看自己的权衡吧。