KVM / QEMU / libvirt 深度指南

在现代 Linux 系统中,虚拟化技术是云计算、HomeLab、软件测试以及安全沙箱的绝对核心基石。与常规第三方虚拟机软件(如 VMware Workstation、VirtualBox)不同,Linux 原生虚拟化方案是由 KVM、QEMU 与 libvirt 三者有机结合而成的。

本文将彻底拆解 Linux 原生虚拟化的技术架构,并提供从 CLI(virsh)到 GUI(Virt-Manager)、从存储池配置到桥接网络连接的全流程实战指南。


1. 原生虚拟化架构拆解

初学者经常混淆 KVM、QEMU 和 libvirt 的关系,实际上它们各自扮演着清晰的角色:

Linux 原生虚拟化三剑客分层分工解剖架构图

1.1 KVM (Kernel-based Virtual Machine)

  • 定位:Linux 内核模块(kvm.ko,以及特定平台的 kvm-intel.ko / kvm-amd.ko)。
  • 作用:利用 CPU 的硬件虚拟化指令集(Intel VT-x / AMD-V),将 Linux 内核直接转变为一个 Type-1 / Type-2 混合型 Hypervisor。它负责管理 CPU 寄存器上下文切换、虚拟内存页表(EPT/NPT)映射以及中断处理。

1.2 QEMU (Quick Emulator)

  • 定位:用户空间纯软件仿真器与虚拟机控制器。
  • 作用:纯靠 KVM 无法运行完整的操作系统,因为虚拟机还需要网卡、显卡、磁盘控制器、USB 总线等外设。QEMU 负责模拟这些硬件设备。当配合 /dev/kvm 使用时,CPU 与内存指令由 KVM 直接在硬件上高速执行,QEMU 仅负责接管外设 I/O。

1.3 libvirt & virsh

  • 定位:跨平台的虚拟化 API 抽象层与守护进程。
  • 作用:直接操控 QEMU 命令行的参数极其繁琐且容易出错。libvirt 将虚拟机的 CPU、内存、存储、网络映射为结构化的 XML 配置文件,并提供标准化的 API(libvirtd / virtqemud 守护进程)与命令行交互工具 virsh

2. 环境检测与全家桶安装

2.1 硬件与内核支持检测

首先确认 CPU 是否支持硬件虚拟化并已在 BIOS/UEFI 中开启:

# 检测 CPU 硬件虚拟化支持 (返回数 > 0 表示支持)
egrep -c '(vmx|svm)' /proc/cpuinfo
 
# 使用 virt-host-validate 综合检查环境
sudo virt-host-validate

确认 KVM 内核模块已加载且具备 /dev/kvm 权限:

lsmod | grep kvm
# 检查当前用户是否在 kvm / libvirt 组中
ls -l /dev/kvm

2.2 安装软件包

在主流发行版上安装原生虚拟化套件:

Ubuntu / Debian:

sudo apt update
sudo apt install -y qemu-system-x86 libvirt-daemon-system libvirt-clients bridge-utils virt-manager ovmf

Arch Linux:

sudo pacman -S qemu-base libvirt virt-manager dnsmasq iptables-nft edk2-ovmf

启用并启动 libvirtd 服务,并将当前用户加入管理组:

sudo systemctl enable --now libvirtd
 
# 将当前用户加入 libvirt 和 kvm 组,免 sudo 管理虚拟机
sudo usermod -aG libvirt,kvm $USER
# 刷新当前 shell 的用户组权限(或重新登录系统生效)
newgrp libvirt

3. CLI 运维:virsh 常用指令速查

virsh 是管理员与 libvirt 守护进程交互的主要工具。

3.1 虚拟机生命周期管理

# 查看正在运行的虚拟机
virsh list
 
# 查看所有虚拟机(包括关机状态)
virsh list --all
 
# 启动虚拟机
virsh start <vmname>
 
# 优雅关机 (向 Guest 发送 ACPI 关机信号)
virsh shutdown <vmname>
 
# 强制拔电源关机
virsh destroy <vmname>
 
# 重启虚拟机
virsh reboot <vmname>
 
# 设置虚拟机随宿主机开机自启
virsh autostart <vmname>
virsh autostart --disable <vmname>

3.2 XML 配置文件导出与编辑

libvirt 采用 XML 描述虚拟机配置:

# 在线修改虚拟机 XML 配置(保存后自动校验)
virsh edit <vmname>
 
# 导出特定虚拟机的 XML 配置文件
virsh dumpxml <vmname> > vmname_backup.xml
 
# 从 XML 文件导入并定义新虚拟机
virsh define vmname_backup.xml
 
# 取消定义(删除)虚拟机配置(保留磁盘镜像)
virsh undefine <vmname>
# 取消定义并同时删除绑定的存储卷与 NVRAM
virsh undefine <vmname> --remove-all-storage --nvram

3.3 快照 (Snapshot) 管理

# 创建内存与磁盘在线快照
virsh snapshot-create-as <vmname> --name "snap-before-update" --description "更新前的快照"
 
# 查看虚拟机的所有快照
virsh snapshot-list <vmname>
 
# 还原虚拟机到指定快照
virsh snapshot-revert <vmname> --snapshotname snap-before-update
 
# 删除快照
virsh snapshot-delete <vmname> --snapshotname snap-before-update

4. 存储池 (Storage Pool) 与磁盘镜像

libvirt 使用“存储池”抽象底层的目录、LVM 逻辑卷或 Ceph 块存储。

4.1 镜像格式选型:qcow2 vs raw

  • raw (原始格式):不加修饰的二进制文件。读写性能略高于 qcow2,但不支持快照、加密与写时复制。
  • qcow2 (QEMU Copy-On-Write)推荐使用。支持动态按需分配空间(Thin Provisioning)、内置多级 COW 快照、AES 级加密与透明压缩。

4.2 存储池管理与 qemu-img 扩容

# 列出系统现有存储池
virsh pool-list --all
 
# 使用 qemu-img 手动创建一个 50G 的 qcow2 镜像
qemu-img create -f qcow2 /var/lib/libvirt/images/ubuntu-disk.qcow2 50G
 
# 查看磁盘镜像详细元数据与实际物理占用
qemu-img info /var/lib/libvirt/images/ubuntu-disk.qcow2
 
# 扩展镜像容量至 100G (注意:调整前虚拟机必须关机)
qemu-img resize /var/lib/libvirt/images/ubuntu-disk.qcow2 +50G
⚠️ 注意:镜像扩容后需扩展 Guest 内文件系统

qemu-img resize 仅扩展了宿主机上的虚拟磁盘块大小。在虚拟机开机后,还需要在 Guest 系统内使用分区调整工具(如 growpart / gparted)和文件系统调整工具(如 Linux 下的 resize2fsxfs_growfs)将新增空间应用到分区中。


5. 虚拟网络架构:NAT 模式 vs 桥接 (Bridge) 模式

libvirt 默认提供一个名为 default 的 NAT 虚拟网络。

[ NAT 模式 ]
Guest (192.168.122.x) <---> virbr0 (NAT / dnsmasq) <---> eth0 (物理网卡) <---> 路由器
 
[ 桥接 模式 ]
Guest (192.168.1.x)   <---+\
Guest (192.168.1.y)   <---+----> br0 (Linux Bridge) <---> eth0 <---> 局域网物理路由器

5.1 NAT 模式(默认 virbr0

  • 特点:虚拟机分配内网私有 IP(如 192.168.122.0/24),可顺畅访问外网,但局域网其他物理机无法直接访问虚拟机(除非设置 iptables/nftables 端口转发)。
  • 查看网络
    virsh net-list --all
    virsh net-dhcp-leases default

5.2 真实局域网桥接 (Bridge br0) 配置

如果希望虚拟机拥有局域网独立 IP(例如 192.168.1.100),需要配置 Linux Bridge。

在宿主机使用 Netplan(以 Ubuntu 为例)创建 br0

# /etc/netplan/01-netcfg.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp3s0:
      dhcp4: false
      dhcp6: false
  bridges:
    br0:
      interfaces: [enp3s0]
      dhcp4: true
      parameters:
        stp: false
        forward-delay: 0

应用配置后,物理网卡 enp3s0 的流量将被桥接到 br0。在 Virt-Managervirsh 配置中将网卡源更改为 Bridge device: br0 即可。

ℹ️ 无线网卡 (Wi-Fi) 桥接限制

标准的 Linux Bridge (br0) 不支持直接绑定 Wi-Fi 无线网卡(受限于 IEEE 802.11 的 3 地址帧头机制)。笔记本电脑若使用 Wi-Fi,建议使用 Macvtap (Bridge mode)Routed NAT Network 作为替代方案。


6. Virt-Manager 图形界面与性能调优建议

6.1 CPU 模式设置:开启 CPU 直通 (Host-Passthrough)

默认情况下 QEMU 使用通用的 qemu64 / kvm64 CPU 虚拟模型,无法向 Guest 暴露宿主机 CPU 的高级指令集(如 AVX2、AVX-512、AES-NI)。

建议在 virsh edit <vmname> 或 Virt-Manager 中将 CPU 模式更改为 host-passthrough

<cpu mode='host-passthrough' check='none'>
  <topology sockets='1' dies='1' clusters='1' cores='4' threads='1'/>
</cpu>

6.2 VirtIO 半虚拟化驱动优化

默认模拟的 e1000 网卡或 ide 磁盘具有相当大的软件开销。强力建议为所有 Linux / Windows Guest 开启 VirtIO 半虚拟化驱动

  1. 磁盘总线 (Disk Bus):设置为 VirtIO(支持 IOthreads 多线程独立处理)。
  2. 网卡型号 (NIC Model):设置为 virtio
  3. 图形控制器:设置为 VirtIO + 勾选 3D Acceleration (Spice / OpenGL)。
💡 Windows 虚拟机 VirtIO 驱动问题

Windows 原生未自带 VirtIO 驱动。在安装 Windows 虚拟机时,需要挂载 Fedora 官方提供的 virtio-win.iso 镜像,在分区选择界面手动加载 vioscsi / viostor 驱动才能识别磁盘。

6.3 CPU Pinning (CPU 绑核) 调优

为了避免 KVM 的虚拟 CPU (vCPU) 在物理 CPU 核心之间频繁上下文切换,可以通过绑核提升缓存命中率:

<!-- 在 virsh edit <vmname> 中添加 vcpupin 配置 -->
<vcpu placement='static'>4</vcpu>
<cputune>
  <vcpupin vcpu='0' cpuset='0'/>
  <vcpupin vcpu='1' cpuset='1'/>
  <vcpupin vcpu='2' cpuset='2'/>
  <vcpupin vcpu='3' cpuset='3'/>
</cputune>

7. 总结

通过 KVM 提供的硬件内核级加速、QEMU 的设备仿真以及 libvirt/Virt-Manager 的标准化管线,Linux 原生虚拟化实现了远超一般桌面虚拟化软件的性能表现。在掌握了存储池与 Bridge 网络之后,你便具备了构建高性能私有云与高级 VFIO 硬件直通的坚实基础。

Navigation