在 Ubuntu 上折腾虚拟化的时候,virt-manager 是我绕不开的一个图形化工具。它把 QEMU/KVM 这套底层能力收拢到一个可交互的窗口里,创建、启动、看控制台、做快照,都不用在终端里敲一大堆参数;装好之后点几下就能把虚拟机跑起来。它解决的是很多人第一步遇到的问题:KVM 本身没有界面,而 virt-manager 正是最常见的图形前端,也是我个人在单机桌面环境里最推荐的方案。这篇文章写给想在 Ubuntu 上快速用起来、但又不希望在命令行和 XML 配置里陷太深的开发者或运维朋友,也欢迎那些已经装了但踩过坑的人对照排查。
1. 为什么要装 virt-manager:桌面 Linux 虚拟化的务实选择
1.1 图形化工具解决什么问题
先说一个很现实的痛点:Ubuntu 默认安装完 QEMU/KVM 之后,你面对的是两个命令行工具,virsh和qemu-system-x86_64。virsh适合管理已经存在的虚拟机,qemu-system-x86_64则要写一长串参数才能启动一个实例,比如磁盘路径、网卡模型、内存大小、CPU 核数、显示输出方式,全部堆在一行命令里。新手一看就头大,哪怕是我这种用了多年虚拟化的人,临时要手动拼一条启动命令,也得翻文档核对参数。
virt-manager 解决的就是这个"入口门槛"。它本身是一个基于 libvirt 的图形化管理程序,通过 libvirt 去和 QEMU/KVM 交互,用户不需要直接接触 XML 文件和 qemu 命令。你能在一个窗口里看到所有虚拟机列表,每台虚拟机的 CPU 占用、内存占用、磁盘吞吐、网络流量都有实时曲线,双击就能打开图形控制台,像操作一台真实电脑一样操作虚拟机。除了基本的创建、开机、关机,它还支持克隆、迁移、快照、VNC/SPICE 连接、存储池管理、网络配置这些功能,对于日常开发和测试完全够用。
1.2 什么场景更适合用 virt-manager
我自己的经验是,virt-manager 特别适合这几类场景:一是个人桌面 Linux 用户,想在本地跑一个 Windows 虚拟机做软件兼容性测试,或者跑另一个 Linux 发行版做实验;二是需要在多个虚拟机之间来回切换的开发者,图形列表比命令行virsh list --all直观得多;三是刚接触 KVM 虚拟化的朋友,用它作为学习入口,等熟悉了里面的概念之后,再回头学命令行会觉得顺手很多。
那是不是所有情况都该用图形界面?也不是。如果是批量创建几十台虚拟机、做自动化交付,那肯定要写virt-install脚本;如果是管理机房里的几百台宿主机,那应该考虑更上层的云管理平台。virt-manager 的定位很明确:单机虚拟化场景下的桌面管理工具。它和 VirtualBox 的用户体验有些接近,但底层走的是 KVM 加速,在 Linux 上的性能损耗比 VirtualBox 的默认配置低一些,也更贴近业界主流虚拟化技术栈。所谓"选型",不是选最复杂的,而是选在当下场景里最省力的,对你来说这就是最合适的工具。
2. 安装前先自检:CPU 虚拟化与系统环境确认
2.1 检查 CPU 虚拟化扩展
动手安装之前,建议先花两分钟确认机器能不能跑 KVM。KVM 的全称是 Kernel-based Virtual Machine,它依赖 CPU 提供虚拟化扩展指令。Intel 系 CPU 对应的标志是vmx,AMD 系 CPU 对应的标志是svm。在终端里执行:
grep -Eoc '(vmx|svm)' /proc/cpuinfo这条命令统计/proc/cpuinfo中每一颗逻辑处理器的信息里出现vmx或svm的次数。如果输出结果大于 0,说明 CPU 的虚拟化扩展已经在系统中可见;如果输出是 0,先别急着装 virt-manager,因为大概率 BIOS/固件里没开启虚拟化功能。
这里要说一个很容易踩的坑:很多人用grep -c vmx /proc/cpuinfo来判断,但这只查了 Intel 的vmx标志,如果你用的是 AMD 平台,可能会误判。我的习惯是把vmx和svm放在一起统计,同时用grep -E '(vmx|svm)' /proc/cpuinfo | head -1看一眼具体输出的内容,确认不是空结果。
如果确认 CPU 支持虚拟化但/proc/cpuinfo里没有标志,通常是固件设置的问题。重启进入主板固件界面,找到类似 "Intel Virtualization Technology"、"SVM Mode" 的选项,把它开启并保存。不同平台的菜单名称不一样,但思路是一致的。需要说明的是,如果你自己运行的也是虚拟机,那要看宿主机是否允许嵌套虚拟化,这个情况我在后面的常见问题里会专门讲。
2.2 确认内核模块与系统版本
接下来看内核是否已经加载 KVM 模块。继续在终端里执行:
lsmod | grep kvm正常情况下你会看到kvm模块,以及对应 CPU 厂商的kvm_intel或kvm_amd模块。如果没有任何输出,可以手动加载:
sudo modprobe kvm sudo modprobe kvm_intel # 或者 kvm_amd,取决于你的 CPU加载之后再执行lsmod | grep kvm确认。同时检查一下设备节点是否存在,以及它的权限:
ls -l /dev/kvm如果看到crw-rw---- 1 root kvm ... /dev/kvm,说明 KVM 设备正常,并且属于kvm组。后面安装 virt-manager 时,当前用户能不能直接用 KVM 加速,很大程度上取决于是否在这个组里。
系统版本方面,virt-manager 在 Ubuntu 的官方软件源里一直都有,我用过的 22.04 LTS 和 24.04 LTS 都能直接安装。可以用lsb_release -a或cat /etc/os-release查看发行版版本,用uname -r查看内核版本。只要不是特别老的内核,正常都支持 KVM。这里唯一要留意的就是:如果你用的是精简版、容器版之类的特殊 Ubuntu 分支,可能连桌面都没有,那装 virt-manager 之前需要先准备好图形环境,因为它本身依赖 GTK 图形库。
3. Ubuntu 上安装 virt-manager 的完整步骤
3.1 一次性装齐相关组件
在 Ubuntu 上安装 virt-manager 并不复杂,核心命令就一条。先更新软件源缓存,再安装:
sudo apt update sudo apt install -y virt-manager libvirt-daemon-system libvirt-clients qemu-kvm这里我习惯把几个包一起装上,而不是只装virt-manager,原因很简单:virt-manager 只是一个前端,它需要 libvirt 服务端和 QEMU/KVM 本体才能真正工作。libvirt-daemon-system负责把 libvirtd 作为系统服务运行起来,libvirt-clients提供virsh和virt-install等命令行工具,qemu-kvm则是 QEMU 在 KVM 模式下的运行环境。如果只装 virt-manager,apt 虽然会自动拉取大部分依赖,但有些环境里 libvirt 服务可能不会被正确配置成开机启动,后面还得手动补。
如果你打算之后用命令行批量创建虚拟机,建议顺手把virtinst也装上,里面包含virt-install工具:
sudo apt install -y virtinstvirt-install和 virt-manager 共用同一套 libvirt 存储池和网络配置,图形界面创建好的虚拟机它也能直接管理,两者不冲突。我通常是一起装好,因为排查问题的时候往往需要virsh来确认状态,而 virt-manager 更适合日常操作。
3.2 启动 libvirtd 并给当前用户提权
安装完成后,还需要确保 libvirtd 服务在运行,并且能开机自启。Ubuntu 上 libvirtd 默认会以 socket 方式启动,但为了避免某些权限和 socket 激活的问题,我习惯先显式启动并启用服务:
sudo systemctl enable --now libvirtd sudo systemctl status libvirtdstatus命令如果显示active (running),说明服务正常。假如你看到的是active (listening)也不要慌,这是 socket 激活的状态,稍后连接到 libvirt 时服务会真正起来。
接下来把当前用户加入libvirt组和kvm组。这一步非常关键,不加入的话,普通用户运行 virt-manager 往往没办法连接系统级的 libvirt,只能退而求其次用 session 级连接,功能受限明显。执行:
sudo usermod -aG libvirt $USER sudo usermod -aG kvm $USER注意:修改组之后,当前终端不会立刻生效,需要重新登录一次,或者运行newgrp libvirt让当前会话临时切换组。我踩过很多次这样的坑:装好软件、加好组,发现还是 Permission denied,结果一查是没重新登录。如果你是通过 SSH 远程操作的,直接退出重进一次最干净。
3.3 首次启动与连接验证
做完上面的步骤,就可以启动 virt-manager 了。终端里执行virt-manager,或者从应用菜单里找到对应的图标。第一次打开时,界面默认会尝试连接本地的qemu:///system,也就是系统级的 QEMU/KVM 服务。连接成功后,左侧栏会显示本地宿主机,QEMU/KVM 是可用状态。
如果没有自动连接,手动点击菜单栏的 "File" -> "Add Connection",在弹出的窗口里选择 Hypervisor 为 "QEMU/KVM",勾选 "Connect to remote host" 并取消勾选。注意这里有个细节:Connection 的 URI 如果是qemu:///session,代表这是当前用户的用户级会话,通常只能管理当前用户创建的虚拟机;而qemu:///system是系统级,能管理所有用户创建的虚拟机和默认网络。一般建议使用qemu:///system,才能看到default网络和系统存储池。
验证是否正常,还可以在终端里执行:
virsh -c qemu:///system list --all如果能看到Id 名称 状态这样一个空的列表,说明当前用户已经具备管理 libvirt 的权限,virt-manager 正常连接也没问题了。
4. 装完后的关键配置:权限、存储与网络
4.1 让当前用户免密管理 libvirt
第 3 节里加入libvirt组的操作,实际上并不保证所有系统 libvirt 操作都对当前用户开放。Ubuntu 桌面版中,libvirt 通过 polkit 做管理员权限控制。你可能遇到的情况是:用virsh -c qemu:///system list --all正常,但打开 virt-manager 后操作某些功能时,系统弹出需要认证的对话框,要求输入管理员密码。
如果觉得每次都输密码很烦,可以给libvirt组用户单独加一条 polkit 授权规则。新建规则文件:
sudo nano /etc/polkit-1/rules.d/80-libvirt-manage.rules填入以下内容:
polkit.addRule(function(action, subject) { if (action.id == "org.libvirt.unix.manage" && subject.isInGroup("libvirt")) { return polkit.Result.YES; } });保存后,无需重启服务,polkit 会动态加载新规则。之后再在 virt-manager 里打开连接,就不会反复要求输密码了。需要强调的是,这个规则只针对libvirt组的用户,不会把权限放宽给所有普通用户,安全边界还是存在的。
如果你偏好更保守的方案,也可以不用 polkit 规则,继续让 virt-manager 弹窗提示输入管理员密码。我个人是建议配好规则,因为实际操作中,virt-manager 在安装虚拟机、调整网络这些环节会多次触发权限校验,每次都弹密码很影响效率。
4.2 配置存储池与磁盘格式
virt-manager 装好之后,通常会看到一个系统默认存储池 "default",路径是/var/lib/libvirt/images。这个目录由 libvirt 服务创建,普通用户一般没有写权限。如果只通过 virt-manager 的图形界面创建虚拟机,它会调用 libvirt 去写,权限没问题;但如果想自己下载一个镜像放进目录里,就需要用sudo cp或者把目录权限调整为当前用户。
这里我建议建一个自己的存储池,实际操作更顺手。在 virt-manager 里选择宿主机,双击打开 "Connection Details",切到 "Storage" 页,点击加号新建存储池。类型选 "Directory Filesystem",路径可以设成你挂载大容量的分区里的一个目录,比如/data/libvirt/images。这样后续虚拟机镜像会放在独立数据盘上,既避免系统盘被虚拟磁盘占用耗尽,又方便迁移和备份。
创建虚拟机时,磁盘格式一般选qcow2。它有几个好处:默认按需分配空间,创建 30G 的磁盘不会立刻占用 30G,而是随着虚拟机实际写入增长;支持快照;支持压缩和 AES 加密。而raw格式直接占用预先分配的空间,性能稍好一点,但不够灵活。我自己的习惯是日常开发虚拟机一律 qcow2,只有极少数对磁盘延迟特别敏感的压测场景才考虑 raw。
4.3 默认 NAT 与桥接网络怎么选
virt-manager 安装完成后,会自动创建一个名为default的 NAT 网络,对应宿主机的virbr0网桥接口。虚拟机使用该网络时,可以访问外网,宿主机也能访问虚拟机,但局域网里的其他设备访问不到虚拟机。这个形态对于大多数测试场景已经够用,我通常只要虚拟机自己能上网、能装软件就行。
如果虚拟机上要跑一个需要被局域网访问的服务,比如网站、API 接口,就必须考虑桥接模式。桥接的思路是把虚拟机的虚拟网卡直接接到物理网络的网桥上,让虚拟机像一台独立主机一样获取局域网 IP。在桌面 Ubuntu 上,最简单的做法是用 NetworkManager 的图形界面创建一个桥接连接,把物理网卡添加为桥接端口,然后在 virt-manager 的虚拟机网络配置里选择这个桥接网络即可。
关于桥接我有一点提醒:不要在断开远程连接的情况下贸然配置桥接。一旦物理网卡被绑定到网桥上,网络连接会短暂中断,如果配置没写好,可能导致宿主机失联,到时候只能跑现场处理。先确认你就在机器旁边,或者有带外管理通道,再来动桥接。网络这块的优先级可以按需调整:测试环境用默认 NAT,生产或对外服务场景用桥接。
5. 快速上手:用 virt-manager 创建第一台虚拟机
5.1 新建虚拟机的完整流程
安装和基本配置搞定之后,创建虚拟机就很简单了。打开 virt-manager,确保已经连接到 QEMU/KVM,点击工具栏左侧第一个带星号的图标,或者按快捷键 Ctrl+N,开始新建虚拟机。
向导一共四步。第一步是选择安装方式,我多数情况下用 "Local install media (ISO image or optical drive)",也就是本地 ISO 镜像文件;如果你已经有做好的虚拟机磁盘镜像,可以选 "Import existing disk image";如果是网络安装源,选 "Network Install (HTTP/FTP)" 并填写 URL。第二步选择 ISO 路径,virt-manager 通常会自动识别系统类型和版本,识别不了就手动选一个接近的,比如装 Ubuntu 24.04 找不到对应条目时,可以选 "Ubuntu 24.04" 或 "Generic Linux"。第三步分配内存和 CPU。第四步设置磁盘容量,可以选择使用现有存储卷,也可以选择创建新卷,格式默认 qcow2,大小按需填写即可。
进到最终页面前,有一个 "Customize configuration before install" 的复选框,我的建议是勾上。它不是必须的,但很有用。勾上之后,点击 "Finish",virt-manager 会带你先打开虚拟机的硬件配置窗口,而不是直接开始安装。在这里能调整显卡型号、显存大小、网卡模型、声卡、引导选项等,省得安装到一半发现硬件配置不适合再返工。调整完点击工具栏的 "Begin Installation",虚拟机会开始启动,并弹出图形控制台窗口,之后就和操作一台普通电脑一样。
5.2 CPU、内存、磁盘分配建议
分配资源是我见过新手最容易出问题的地方。我个人的建议是:如果你的开发机是 8 核 16G 内存,第一个测试虚拟机分 2 核 4G 就够用了,不用贪多。虚拟机多核跑起来的时候,宿主机如果资源不足,会出现明显的卡顿,特别是机械硬盘环境下,I/O 等待会拖垮整个系统的交互体验。如果想要更流畅一些,可以考虑给虚拟机少分配一个核,比如物理 8 核,给虚拟机 4 核以内,留足宿主机余量。
内存分配同样要留余地。我见过身边不少人给虚拟机分了 12G,然后宿主机还剩 2G,结果浏览器都打不开。另一个容易忽略的点是:virt-manager 默认允许宿主机动态回收虚拟机的空闲内存,性能敏感的应用建议在虚拟机 XML 的 memory 配置里关掉气球驱动,或者调大currentMemory,避免内存频繁抖动。
磁盘方面,有两点经验供参考:一是存储卷默认放在系统盘的话,注意容量不能填太大,qcow2 虽然按需增长,但增长到一定量之后宿主机磁盘满了,虚拟机直接 I/O 错误;二是安装系统时尽量让虚拟机内部的引导方式与固件保持一致,现在多数发行版默认 UEFI,virt-manager 在新建虚拟机会根据系统类型自动设置,手动调整时不要乱改。
6. 常见问题与排查技巧实录
6.1 权限类报错:"无法连接到 libvirt"
很多人装完 virt-manager 双击桌面图标,报出来的第一句英文就是Unable to connect to libvirt.后面还可能跟着Permission denied或者Authentication failed。这大概率不是安装问题,而是权限没配好。
排查顺序我建议这样:先确认当前用户在不在libvirt组里,执行groups;如果不在,回第 3.2 节把人加进去并重新登录。如果在组里仍然报权限错误,再看 polkit 规则是否生效,确认/etc/polkit-1/rules.d/80-libvirt-manage.rules文件的内容和权限,之后用virsh -c qemu:///system list --all做一次快速验证。命令行能通过、图形界面不行的情况,通常还是 polkit 对话框被打断或者被系统策略拦截。
临时应急可以用sudo virt-manager启动,但我不建议拿这个做长期方案。root 权限跑图形应用风险很高,而且 virt-manager 有正常的多用户授权方案,花几分钟配置好,后面能省掉一堆麻烦。
6.2 加速类报错:"KVM acceleration not available"
创建虚拟机或者启动虚拟机时,报KVM acceleration is not available,当前配置无法获得硬件加速。这事儿分两层来看。
第一层是宿主机层面的虚拟化支持没开或模块没加载。回到第 2.1、2.2 节的内容,检查/proc/cpuinfo、lsmod | grep kvm、ls -l /dev/kvm,一个都不满足就按对应方法处理。第二层是应用层权限问题:/dev/kvm存在于但用户不在kvm组里,同样会导致加速不可用。ls -l /dev/kvm能看到属组是否为kvm,把用户加入kvm组并重新登录即可。
还有一种容易被忽略的情况:你在虚拟机里再套了一层虚拟机。这时候里层虚拟机想用 KVM,需要宿主机虚拟化平台开启嵌套虚拟化功能。我的某次测试是在一个 QEMU/KVM 虚拟机里继续装 KVM,结果内层始终报加速不可用,最后确认是外层虚拟机的 CPU 模式没开嵌套。在 virt-manager 里把虚拟机的 CPU 配置改为host-passthrough或勾选对应的 hypervisor 选项,重启虚拟机后/proc/cpuinfo能再看到 vmx/svm 标志,问题就解决了。
6.3 虚拟机启动后黑屏或控制台空白
安装系统或启动虚拟机时,图形控制台一直是黑的,但虚拟机进程还在跑。这个问题在 UEFI 引导和显卡配置不当的组合下比较常见。
如果是安装 Windows 虚拟机,建议在硬件配置里把 Display 设为 SPICE,Video 设为 QXL,显存至少 16M;如果是安装 Linux,Video 可以放 Virtio,配合 SPICE 体验最好。如果安装过程中黑屏,试着把 Video 改成VGA或VMWare compatible,这两种兼容性最好,缺点是性能不如 QXL/Virtio,但能先保证安装流程走完。装完系统之后再换回更优的显卡模型,同时安装对应的图形驱动。
还有一种"控制台空白"不是黑屏,而是窗口打开了但内容没有刷新,尤其是在用 VNC 连接远程虚拟机时比较常见。这个时候先别急着重启虚拟机,检查一下 virt-manager 窗口里的 View 菜单,看是不是选择了错误的 console 类型;远程场景下也要确认宿主机上对应端口的防火墙规则没有拦截 SPICE/VNC 流量。
6.4 通用排查思路与必备命令
遇到 virt-manager 相关的报错,我一般按照"服务 -> 权限 -> 日志"的顺序排查,而不是直接打开图形界面反复重试。先把服务状态确认掉:
systemctl status libvirtd journalctl -u libvirtd -n 50 --no-pagerjournalctl里面通常会给出最直接的错误原因,比如某个存储目录不存在、某个网络桥接失败、XML 解析报错。看到关键字后再去针对性处理。进程级别的异常可以看:
dmesg | tail -30比如 KVM 模块加载失败、设备节点冲突,内核日志里会有记载。如果虚拟机本身启动异常,用virsh list --all配合virsh dominfo 虚拟机名查看状态,再用virsh start 虚拟机名从命令行启动,观察报错信息。很多问题在图形界面里被简化为一条看不懂的英文提示,但到命令行执行反而会输出完整上下文,定位反而更快。
最后分享一个小习惯:新建虚拟机后,先别急着装系统,用virsh dumpxml 虚拟机名导出一次配置,备份下来。后面遇到问题时,这个 XML 文件能帮你快速还原环境,也能和对正常虚拟机的配置做 diff,找出被改坏的字段。
7. 一点个人实操经验与后续扩展
7.1 我的使用习惯
用了一段时间 virt-manager 之后,我逐渐形成了一套自己的使用套路:图形界面管日常,命令行管排查和自动化。平常创建临时测试虚拟机,直接在 virt-manager 里点几下,几分钟搞定;需要批量部署、做基准测试时,则写virt-install脚本配合virsh操作,把同样的参数模板化复用。
镜像检查方面,我会定期用qemu-img info看虚拟磁盘的实际占用,避免 qcow2 文件膨胀到异常。备份虚拟机时,尽量在虚拟机关机状态下用cp --reflink=auto或者qemu-img convert生成副本,这样不会出现文件系统层面不一致的问题。如果虚拟机里有重要数据,我还会先在虚拟机内跑一次fstrim,让空闲块被回收,之后再做镜像压缩,效果明显。
7.2 可以继续扩展的方向
virt-manager 能做的事远不止创建虚拟机。如果你已经能用它管理本地虚拟机,下一步值得研究的方向有三个:第一,用virsh migrate在宿主机之间迁移虚拟机,配合共享存储就能做在线迁移;第二,GPU 直通(PCI passthrough),把宿主机显卡直通给虚拟机,需要硬件支持 IOMMU,配置复杂度高但性能提升很大;第三,用 libvirt hooks 在虚拟机生命周期事件里自动执行脚本,比如在启动时自动挂载备份盘、在关机时自动执行收尾任务。
这些进阶功能有个共同点:都是建立在理解 libvirt 基础概念之上的。而 virt-manager 恰恰是理解这些概念的最佳入口。先把图形界面用熟练,再把每个操作背后生成的 XML 配置反推看懂,整个 KVM 虚拟化体系也就慢慢立起来了。这也正是我为什么一直建议新手别跳过 virt-manager、直接学命令行的原因。