资讯详情

libvirt安装实战:从环境检查到创建第一台虚拟机与排错

📅 2026/10/24 0:46:38 | 华诺云谱 👁 阅读
libvirt安装实战:从环境检查到创建第一台虚拟机与排错
1. 先搞清楚要装的是什么libvirt 这一层到底管什么很多人在安装 libvirt 之前其实对它的定位是模糊的。你可能会问我直接用 qemu-system-x86_64 命令不也能启动虚拟机吗为什么还要额外装一个 libvirt 和一堆配套的包这里要先理清一个概念KVM/QEMU 负责的是底层的 CPU 虚拟化和设备模拟也就是真正在跑虚拟机的那部分。而 libvirt 是站在它们上面的一层统一管理接口它本身不模拟任何硬件也不执行任何虚拟 CPU 指令它做的是三件事定义虚拟机、调度虚拟机生命周期、统一配置资源。换句话说libvirt 是一个虚拟化管理中间层。它给你提供了一套稳定的 API 和命令行工具让你不用去记不同 hypervisor 各自的命令格式。今天你用 KVM明天想用 LXC 容器甚至想管理远端宿主机上的虚拟机对于上层工具来说调用 libvirt 的方式几乎不变。libvirt 装好之后你的系统里会多出几个关键组件libvirtd后台守护进程所有管理请求都经由它转达给具体的 hypervisorvirsh命令行管理工具日常操作虚拟机主要靠它virt-install / virt-clone从镜像创建虚拟机、克隆已有虚拟机的专用工具virt-manager图形化管理界面前端图形化封装底层还是调用 libvirt 的 APIlibvirt-client 相关库文件给其他语言如 Python 的 libvirt-python提供开发接口。这个内容适合谁如果你是运维、虚拟化平台开发者或者只是想在个人电脑上搭一套 KVM 实验环境那 libvirt 都是绕不开的一环。这篇内容会覆盖从环境检查、安装方式选型、装完后的权限与网络配置到第一台虚拟机的创建和常见报错排查尽量让你一次走通。2. 装之前的评估环境不达标装完也跑不起来2.1 CPU 虚拟化支持是第一道门槛libvirt 本身是纯软件但它要管理的 KVM 需要硬件辅助虚拟化。所以在安装之前先确认你的 CPU 支持并已开启虚拟化扩展grep -E -o (vmx|svm) /proc/cpuinfo | sort -uIntel 平台显示 vmxAMD 平台显示 svm。如果这里没有输出大概率是 BIOS/UEFI 里没开虚拟化开关或者你的 CPU 型号本身不支持。还有一种情况是你现在这台机器本身就是一个虚拟机那就要看宿主是否开启了嵌套虚拟化这一层没打开guest 里面再装 KVM 会非常痛苦。更直接的检查方式是看设备节点是否存在ls -l /dev/kvm有这个节点说明内核 KVM 模块已经加载成功。如果文件不存在试着加载模块modprobe kvm_intel # Intel 平台 modprobe kvm_amd # AMD 平台模块加载失败时可以看内核日志定位原因常见的包括 BIOS 未开启虚拟化、已有其他管理程序占用 VT-x 等。2.2 架构、内核版本与内存规划接着确认系统架构uname -m绝大多数场景是 x86_64但 ARM64aarch64平台也能跑 KVM 加 libvirt只是发行版包名略有差异。内核版本建议在较新的长期支持版本以上太老的内核可能存在 cgroup、网络过滤方面的兼容问题连带着 libvirtd 在启动时也会出现各种莫名其妙的告警。内存方面libvirtd 本身很轻占的内存可以忽略不计真正吃内存的是你要跑的虚拟机。但有个容易被忽略的点libvirt 默认给每个虚拟机的 QEMU 进程创建一个 cgroup所有 guest 的总内存和 CPU 配额受宿主机整体资源约束。如果你打算跑多个虚拟机先估算一下总量免得后面物理内存不够导致 guest 被 OOM 杀掉。2.3 先决定装到哪种程度libvirt 的安装不是单一一个包而是一组互相依赖的包。根据使用场景装的东西可以差很多只要命令行管理libvirt-daemon、libvirt-client 就够还要能从镜像创建虚拟机加 virt-install桌面环境想要图形界面加 virt-manager要在浏览器里管理考虑 cockpit 的虚拟机插件。我接触过不少新手上来就只装一个 libvirt0结果发现根本没有 virsh 命令这就是没搞清楚包之间的分工。下面一节会给出完整的安装命令。3. 三条安装路线软件源安装、容器部署、源码编译3.1 发行版软件源安装是最稳妥的选择对绝大多数人来说不要自己折腾源码编译直接用发行版仓库里的包是最省心的方案。软件的打包、依赖、服务文件、默认配置都已经帮你处理好了。Debian 系发行版下的完整安装sudo apt update sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager这几个包的分工大概是qemu-kvm底层 hypervisor提供 /usr/bin/qemu-system-x86_64 libvirt-daemon-system包含 libvirtd 守护进程、socket 激活单元和默认的 AppArmor 策略libvirt-clients包含 virsh 等命令行工具bridge-utils提供 brctl 工具建网桥的时候会用到virtinst提供 virt-install、virt-clonevirt-manager图形化管理界面。RHEL/CentOS 系发行版下可以直接用虚拟化组包sudo dnf install virtualization这条命令会一次拉进来 KVM、libvirt、virt-install以及相关的管理前端组件。手动拆开装的话就是sudo dnf install -y qemu-kvm libvirt virt-install装完注意不同发行版的服务名可能略有差异Debian 系通常直接用libvirtd有的新版本用libvirtd.socket做 socket 激活。务必用 systemctl 确认之后再往下走。3.2 容器里跑 libvirtd适合测试不适合生产如果你想把 libvirtd 跑在容器里比如在一个统一的基础镜像里做虚拟化控制平面的开发可以做但要把几个关键设备透传进去docker run -d \ --name libvirt-test \ --device /dev/kvm \ -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ -v /var/lib/libvirt:/var/lib/libvirt:rw \ --network host \ libvirt/libvirtd容器化部署的坑很多最典型的是 /dev/kvm 访问权限和 cgroup 挂载的读写权限。容器里的模块加载、udev 规则、AppArmor/SELinux 策略都和宿主机不完全一致经常会出现 libvirtd 启动正常但一创建虚拟机就报 monitor 连接失败的问题。我自己的实践体会是容器方式适合做 API 层面的功能测试和 CI 环境生产环境老老实实用宿主机安装的方式省下的那点隔离性远远补不上踩坑的时间成本。还有一点要特别注意如果你本身的宿主机就是一台虚拟机那容器里的 libvirtd 同样需要嵌套虚拟化支持没有 /dev/kvm 的话QEMU 会退化成纯软件模拟TCG 模式性能完全没法看。3.3 源码编译安装什么人才需要这么做源码编译的情况越来越少一般只有这三种诉求定制编译选项、目标发行版的仓库里软件版本太旧、或者你在做嵌入式和交叉编译相关的定制。libvirt 的编译依赖较长一串开发库包括 gcc、make、pkg-config、glib2-devel、libxml2-devel、yajl-devel、libnl3-devel 等。基本步骤如下tar -xzf libvirt-*.tar.gz cd libvirt-* meson setup build --prefix/usr -Ddriver_qemuenabled meson compile -C build meson install -C build新版 libvirt 已经迁移到 meson 构建系统configure 脚本时代已经过去了。编译本身通常几分钟能跑完但真正麻烦的是后置工作你要自己处理 systemd 服务单元、/etc/libvirt 下的默认配置、SELinux/AppArmor 策略。这些在发行版打包时都替你做好了源码装完这些全得自己补漏掉任何一个后面用起来都别扭。所以我给的建议很直接没有特殊理由直接用发行版仓库。编译这条路知道流程即可不值得为了尝鲜付出配置成本。4. 装完后的配置权限、网络、存储一个都不能漏4.1 让当前用户能管理虚拟机安装完成后第一件事是确认服务状态sudo systemctl status libvirtd如果没启动先启动并设置开机自启sudo systemctl enable --now libvirtd然后把你的当前用户加入到 libvirt 和 kvm 用户组否则每次执行 virsh 都得加 sudosudo usermod -aG libvirt,kvm 你的用户名这里解释一下为什么libvirtd 默认以 root 身份运行但它的访问策略通过 polkit 控制。系统里会有 libvirt 和 libvirt-qemu 这样的系统用户组把普通用户加进 libvirt 组之后这个用户才能通过 polkit 的默认规则获得 qemu:///system 域的管理权限。改完用户组之后需要重新登录一次才能生效这是很多人第一次执行 virsh list 报 Permission denied 的原因。另外要分清两个连接 URIvirsh -c qemu:///system list --all virsh -c qemu:///session list --allsystem 是需要系统级权限的持久域虚拟机以 libvirt-qemu 系统用户的身份运行适合放到后台长期跑session 是用户级域仅对当前登录用户可见虚拟机进程以你自己的用户身份运行。刚入门的朋友如果发现 virsh list 和图形界面看到的虚拟机列表对不上多半就是搞混了这两个域。4.2 默认网络你一定用得上装完 libvirt系统里默认会定义一个名为 default 的 NAT 网络但很多发行版默认不会自动启动它。检查一下virsh net-list --all如果看到 default 显示为 inactive启动并设置自动启动virsh net-start default virsh net-autostart default这个网络做了什么事它会在宿主机上创建一个名为 virbr0 的网桥IP 段通常是 192.168.122.0/24libvirtd 还会拉起一个内嵌的 dnsmasq 负责给虚拟机分配 IP 和做 DNS 解析。虚拟机只要在配置里绑定了 networkdefault就能拿到一个 192.168.122.x 的地址由宿主做 NAT 转发出去上网。平时常见的一个坑是宿主机上你自己跑了一个 dnsmasq 或别的 DHCP 服务占了 53 或 67 端口导致 default 网络启动时报 dnsmasq 起不来。解决方法是换掉默认网络的 IP 段或者干脆停掉你自建的那个服务。还有一个更隐蔽的问题部分云厂商的 VPC 内部已经使用了 192.168.122.0/24 网段网络冲突会让虚拟机网络时通时断这种情况建议直接编辑 default 网络换一个网段。4.3 默认存储池确认与磁盘规划libvirt 管理存储的逻辑是存储池加卷。安装后默认有一个 pool 指向 /var/lib/libvirt/images所有虚拟机的磁盘镜像默认放这里virsh pool-list查看默认池的信息virsh pool-info default这个目录默认属于 root 用户和 libvirt 组权限倒是没问题但要留意磁盘空间。很多人虚拟机建到一半才发现根分区不够而 /var/lib 恰恰在根分区的场景很常见尤其是一些默认分区方案里 /var 没有单独划分的系统。建议先看看磁盘剩余空间df -h /var/lib/libvirt/images空间紧张的话可以建一个新的存储池指向别的分区或数据盘virsh pool-define-as data dir - - - - /data/libvirt-images virsh pool-build data virsh pool-start data virsh pool-autostart data之后创建虚拟机的时候直接用 --disk pooldata 指定就行了。4.4 socket 激活与 polkit 的互动现代发行版里 libvirtd 默认走 socket 激活libvirtd.socket 在监听到连接时才拉起主服务这样能减少闲置占用的系统资源。如果你发现 systemctl status libvirtd 显示 activerunning但进程列表里找不到 libvirtd别慌多半是 socket 激活模式在起作用。这个机制的副作用是日志里偶尔会出现连接中断或重启服务后才生效配置的现象。改完 /etc/libvirt/libvirtd.conf 之后习惯性重启这两个单元sudo systemctl restart libvirtd.socket libvirtd.service很多人在改配置之后只 restart 了 libvirtd.service结果发现配置没生效其实就是忘了把 libvirtd.socket 一起重启因为连接还复用在旧的 socket 描述符上。5. 验证安装成果从版本检查到创建第一台虚拟机5.1 基础自检服务和权限都搞定后先看版本信息virsh version这里能看到三部分数据virsh 本身版本、libvirt 库版本、底层的 QEMU 版本。三者的版本号不必完全一致但不要相差太远否则会出现 API 兼容性告警。接下来用工具直接检测宿主机虚拟化能力virt-host-validate这个命令会逐项检查 CPU 虚拟化、硬件支持、安全模块、cgroup 等任何 FAIL 项都会在这里暴露出来。确认能连上守护进程并列出虚拟机virsh list --all刚装完应该没有任何虚拟机但命令能正常执行且不报错就说明链路已经是通的了。5.2 用 virt-install 创建第一台虚拟机安装一部 Linux 虚拟机的典型命令如下sudo virt-install \ --name demo \ --memory 2048 \ --vcpus 2 \ --disk path/var/lib/libvirt/images/demo.qcow2,size20,formatqcow2 \ --os-variant ubuntu22.04 \ --network networkdefault \ --graphics none \ --location /path/to/iso或http://安装源几个参数选型上多解释一句disk 的 format 建议选 qcow2qcow2 是稀疏文件创建时只占很小空间按需增长还支持快照和压缩。raw 格式性能稍好一点但没有这些衍生特性os-variant 可以用osinfo-query os查可用列表它决定了虚拟机的默认设备模型和驱动选择选对了能避免很多启动失败的问题如果你想在纯命令行环境安装--graphics none 会启用文本模式安装安装完成之后可以用 virsh console demo 进入虚拟机终端。如果是在桌面环境把 --graphics none 去掉virt-manager 或 virt-viewer 会弹出图形窗口。安装完的虚拟机查看和管理virsh list --all virsh start demo virsh console demo virsh reboot demo virsh shutdown demo virsh destroy demo # 强制断电类比拔电源这里要提醒一下destroy 在英文里名字看起来很重但它对 KVM 虚拟机来说就是强制关机的意思不会误删磁盘文件。真正常见的误操作反而是virsh undefine这个命令会删除虚拟机定义配合 --remove-all-storage 参数还会连带删除磁盘镜像执行前一定确认这不是你要保留的数据。5.3 快照与克隆装完之后值得马上试的两个功能虚拟机跑起来之后第一时间建议试试快照virsh snapshot-create-as demo first-snapshot 安装完成后 virsh snapshot-list demo virsh snapshot-revert demo first-snapshotqcow2 格式下快照几乎是瞬时完成的因为写时复制机制只记录差异数据。这个功能在折腾系统、测试软件时是救命稻草遇到搞坏的配置直接回滚不用重装。克隆也是一行命令的事virt-clone --original demo --name demo-clone --auto-clone它会自动为新虚拟机生成新的磁盘镜像和新的 MAC 地址省去手动改配置的麻烦。但注意克隆出来的虚拟机如果两台上电同时运行在同一个网络里主机名和 SSH 密钥都是同一套需要进系统重新配置这是很多人克隆完发现两台机器像双胞胎的原因。6. 高频报错排查我把踩过的坑整理成了一张速查表報错现象根本原因处理方式virsh 提示无法连接 socketConnection refusedlibvirtd 服务未启动或 socket 被禁用systemctl start libvirtd检查 libvirtd-tcp.socket / libvirtd.socket 状态连接成功但 virsh list 报 Permission denied当前用户不在 libvirt 组polkit 策略未生效加入 libvirt 组并重新登录确认没有自定义 polkit 规则挡掉普通用户启动 default 网络失败日志显示 dnsmasq 出错宿主机 53/67 端口被占用或网段冲突编辑 default 网络换 IP 段排查自建 DNS/DHCP 服务创建虚拟机时 kvm_intel 模块加载失败BIOS 未开 VT-x或宿主未开启嵌套虚拟化进 BIOS 开启虚拟化在宿主机验证 /dev/kvm 存在虚拟机启动后卡住日志出现 monitor connection resetQEMU 进程被安全模块拦截或 cgroup 资源不足检查 AppArmor/SELinux 日志调整相应策略查看 dmesg 里 OOM 记录virsh console 连不上黑屏无输出虚拟机没有配置串口控制台创建时加 --graphics none --extra-args consolettyS0或安装完在 guest 里配置 gettydestroy 之后虚拟机定义还在启动提示重复忘了 undefine 或定义里磁盘路径占用先用 undefine 清除定义确认磁盘文件没有被其他虚拟机占用两个虚拟机网络冲突IP 时有时无克隆后 MAC 地址重复用 virt-clone --auto-clone 重新生成 MAC手动改 ifcfg 里的 HWADDR再补充一个很隐蔽的坑日志里出现 AppArmor 拒绝访问某个 qcow2 文件的记录但你的磁盘路径明明在 /var/lib/libvirt/images 下。这种通常是之前手动移动过镜像文件文件的 security label 没有跟着走。解决方法是把镜像放回默认池路径或者用chcon/ AppArmor 的 profile 调整不要图省事直接把 AppArmor 整个禁用那等于拆了安全层。另外如果你在虚拟机里又装了 KVM 做嵌套实验记得确认宿主和 guest 两边都把嵌套虚拟化打开。Intel 平台宿主机上通常这样做echo options kvm_intel nested1 /etc/modprobe.d/kvm_intel.conf重启后 guest 里能看到 vmx 标志位才说明这条链路是通的。7. 最后分享一点我的实操体会装 libvirt 这件事表面上看是几条安装命令实际上真正的复杂度都在装完之后。我个人的建议是装完先别急着上图形界面和自动化的管理工具先用 virsh 命令行把网络、存储、快照这些概念亲手操作一遍。命令行工具的输出自带完整信息报错也直接能帮你把 libvirt 的内部机制摸清楚之后再接触那些封装好的面板或 API遇到问题你也不会慌。另外一个小技巧改任何 /etc/libvirt 下的配置之前先备份一份。libvirt 的配置解析非常严格一个 XML 标签写错可能导致整个服务起不来有备份兜底能省下大把排查时间。虚拟机这块也一样/var/lib/libvirt/images 里的磁盘镜像就是你的全部身家定期做快照或者定期备份等真正用到的时候你会回来感谢这个习惯。如果你能把第一台虚拟机从创建、克隆到快照回滚完整走一遍libvirt 这层的基本功就算扎实了。后面再接触 OpenStack、Ovirt 这些上层平台你会发现它们底层全是这一套东西到时候再回头看这个安装文档感触会完全不同。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑