系统环境:Ubuntu 24.04,宿主机磁盘:sda 系统盘,sdb 465G 裸盘做虚拟机 LVM 存储,支持网页 Cockpit 管理、PCIe 显卡直通。记录完整流程 + 实际踩坑排错,拿来就能照着部署。

一、搭建前检查:确认 CPU 虚拟化是否开启

必须 BIOS 打开 Intel VT‑x / AMD‑V,否则 KVM 无法工作。

# 查看CPU是否开启虚拟化,输出大于0代表开启成功
egrep -c '(vmx|svm)' /proc/cpuinfo

再确认 KVM 内核模块是否正常加载

lsmod | grep kvm

正常输出示例

kvm_intel             540672  0
kvm                  1507328  1 kvm_intel
irqbypass              16384  1 kvm
  • kvm_intel:Intel 平台 KVM 驱动;AMD 平台这里是kvm_amd

  • kvm:KVM 核心虚拟化框架

  • irqbypass:虚拟机中断直通依赖

  • ⚠️kvm_intel后面数字0:代表当前没有运行虚拟机,属于正常,启动虚拟机数字会增加。

二、安装 KVM 虚拟化全套组件

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

各个包通俗解释:

表格

软件包

作用

qemu‑kvm

真正虚拟机执行引擎,CPU 内存磁盘模拟,调用硬件虚拟化

libvirt‑daemon‑system

libvirtd 后台服务,管理虚拟机启停、快照、网络存储

libvirt‑clients

virsh 命令行工具集,终端管理虚拟机

bridge‑utils

网桥工具,实现虚拟机桥接局域网,拿到真实内网 IP

virt‑manager

桌面 GUI 虚拟机管理器,有桌面环境才用

ovmf

UEFI 固件,替代传统 BIOS;Win11、显卡直通强烈建议 UEFI 启动

swtpm

TPM2.0 模拟器,满足 Win11 安装 TPM 硬件要求

启动 libvirt 服务并设置开机自启

sudo systemctl enable --now libvirtd

用户权限配置(很关键)

sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
  • libvirt组:控制 libvirtd 服务,普通用户可以操作 virsh/virt‑manager,不加每次必须 sudo

  • kvm组:访问/dev/kvm设备;直接裸跑 qemu 命令需要,libvirt 后台 root 运行可以不依赖,稳妥建议两个都加上。

✅重点:修改用户组之后,必须注销重新登录 SSH / 桌面会话,权限才生效;单纯 sudo 不会刷新用户组!

三、裸盘 sdb 制作 LVM,给虚拟机做存储池

目标:整块 465G 磁盘 sdb,全部交给虚拟机,虚拟机磁盘全部落在 sdb,不占用系统盘 sda。

1、擦除磁盘原有分区信息

先看磁盘设备名

lsblk

本例磁盘为/dev/sdb,删掉原有分区表,清空磁盘元数据

sudo wipefs -a /dev/sdb

执行完再次 lsblk 确认 sdb 没有任何子分区。

2、创建 LVM 物理卷、卷组

# 将整块sdb创建物理卷PV
sudo pvcreate /dev/sdb

# 创建卷组vg‑vmdata
sudo vgcreate vg-vmdata /dev/sdb

# 查看卷组状态
sudo vgs

成功输出:vg‑vmdata,空闲容量 465.76G。

3、Libvirt LVM 存储池(踩坑重点!网上大量教程 XML 错误)

❌网上很多旧教程使用标签<vgname>vg‑vmdata</vgname>Debian/Ubuntu libvirt 不识别这个标签! libvirt 忽略不识别标签,会拿存储池名字当做 LVM 卷组名字去查找,直接报错:cannot find logical volume group name 'vm‑lvm‑pool'

区分两个名字,千万不要搞混:

表格

名称

归属层

说明

vm‑lvm‑pool

libvirt 层

存储池名字,仅 libvirt 识别,操作系统 LVM 看不到

vg‑vmdata

系统 LVM 层

真实物理卷组,vgs 命令能看到

✅正确 XML 写法,使用<source><name>真实卷组名</name></source>

cat <<'EOF' > /tmp/vm-pool.xml
<pool type='logical'>
  <name>vm-lvm-pool</name>
  <source>
    <name>vg-vmdata</name>
  </source>
  <target>
    <path>/dev/vg-vmdata</path>
  </target>
</pool>
EOF

注册、启动、开机自启存储池

sudo virsh pool-define /tmp/vm-pool.xml
sudo virsh pool-start vm-lvm-pool
sudo virsh pool-autostart vm-lvm-pool

# 校验状态
sudo virsh pool-list --all
sudo virsh pool-info vm-lvm-pool

# 删除临时xml文件
rm /tmp/vm-pool.xml

成功标志:状态running,容量 465.76GiB,可用空间全部空闲。

四、配置 libvirt 默认 NAT 网络 default

绝大多数场景使用 NAT 网络,虚拟机可以访问外网。

cat <<'EOF' > /tmp/default-net.xml
<network>
  <name>default</name>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>
EOF

sudo virsh net-define /tmp/default-net.xml
sudo virsh net-start default
sudo virsh net-autostart default
rm /tmp/default-net.xml

# 查看网络状态
sudo virsh net-list --all

确认 default 网络状态为activeautostart yes

五、两种虚拟机管理方式

方式 1:Cockpit 网页管理(无桌面服务器首选,浏览器访问)

直接 apt 安装会找不到cockpit‑machines,Ubuntu 需要从 backports 源安装。

# 加载系统版本代号
. /etc/os-release

# backports源安装
sudo apt install -t ${VERSION_CODENAME}-backports cockpit cockpit-machines -y

# 启动服务
sudo systemctl enable --now cockpit.socket

# 防火墙放行9090端口
sudo ufw allow 9090/tcp

查看宿主机 IP

ip a

浏览器访问:https://宿主机IP:9090,使用宿主机系统账号密码登录,左侧菜单【机器】管理虚拟机和存储池。

方式 2:桌面图形界面 virt‑manager

适合本地有桌面的机器,终端直接运行

virt-manager

创建虚拟机几个关键要点

  1. ISO 镜像:系统镜像放在系统盘 sda 即可;

  2. 磁盘:存储池选择vm‑lvm‑pool,磁盘就落到 sdb,不占用系统盘;

  3. 固件:选择 OVMF (UEFI),Win11 必须,显卡直通也推荐 UEFI;

  4. 磁盘、网卡总线统一选virtio,性能最优;

  5. 网络:使用 default NAT 网络。

六、Intel 平台显卡 PCI 直通前置配置(RX580 等 AMD 显卡)

前提:BIOS 开启 Intel VT‑d (IOMMU)

1、确认 IOMMU 是否识别

sudo dmesg | grep -i iommu

输出有 IOMMU 分组信息,代表硬件支持 IOMMU。

2、修改 GRUB 开启 IOMMU

sudo nano /etc/default/grub

修改内核参数:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt"

保存退出,更新 grub 并重启

sudo update-grub
sudo reboot

重启后校验 IOMMU 是否成功开启

dmesg | grep -i DMAR

看到DMAR: IOMMU enabled代表内核 IOMMU 开启成功。

3、安装 vendor‑reset 模块(解决 AMD 显卡 RX580 直通复位 bug)

很多 AMD 显卡虚拟机关机后显卡无法复位,宿主机卡死,需要 vendor‑reset 内核模块。

# 安装编译依赖
sudo apt install git dkms build-essential linux-headers-$(uname -r)

# 拉取源码
git clone https://github.com/gnif/vendor-reset.git
cd vendor-reset

# dkms编译安装内核模块
sudo dkms install .

# 设置开机自动加载模块
echo "vendor-reset" | sudo tee -a /etc/modules

# 更新启动镜像
sudo update-initramfs -u

校验模块安装

dkms status

重启宿主机,验证模块加载

lsmod | grep vendor_reset

后续就可以在 virt‑manager 或者 Cockpit 里面把显卡 PCI 设备直通给虚拟机。

七、部署完成后整体状态核对清单

✅ CPU 硬件虚拟化 vmx 开启 ✅ kvm 内核模块正常加载 ✅ qemu‑kvm、libvirt 全套软件安装完成 ✅ libvirtd 开机自启正常运行 ✅ sdb 磁盘创建 LVM 卷组vg‑vmdata ✅ libvirt 存储池vm‑lvm‑poolrunning,465G 可用 ✅ default NAT 网络 active 自动启动 ✅ 用户加入 libvirt、kvm 组,已重新登录刷新权限 ✅ IOMMU 内核开启,显卡直通前置条件就绪 ✅ vendor‑reset 模块就绪,规避 AMD 显卡复位故障

后续直接新建虚拟机,磁盘选择 LVM 存储池,配置 PCI 直通硬件即可。