保姆级教程:在Ubuntu 22.04上用virt-manager给KVM虚拟机直通GPU/网卡(含VFIO配置避坑)
保姆级教程:Ubuntu 22.04下KVM虚拟机GPU/网卡直通全攻略
刚接触虚拟化的开发者常会遇到这样的困境:虚拟机里的3D建模软件卡成幻灯片,AI训练任务比物理机慢三倍,或者网络测试时延迟高得离谱。PCIe直通技术正是解决这些痛点的钥匙——它能让虚拟机直接接管物理设备,性能损失几乎可以忽略不计。本教程将手把手带你在Ubuntu 22.04上,用virt-manager图形化工具完成GPU和网卡的直通配置,特别针对NVIDIA/AMD显卡和Intel/Realtek网卡给出详细避坑指南。
1. 前期准备:硬件与BIOS的生死契约
在开始前,请先确认你的硬件支持以下特性:
- CPU:Intel VT-d或AMD-Vi技术(可在终端输入
grep -E '(vmx|svm)' /proc/cpuinfo验证) - 主板:BIOS中需开启以下选项(不同主板位置可能不同):
- Intel平台:VT-x、VT-d、Above 4G Decoding
- AMD平台:SVM Mode、IOMMU、ACS Support
- 显卡:建议准备两张(一张给宿主机,一张直通)
- 网卡:推荐Intel I350或82576等支持SR-IOV的型号
注意:部分消费级主板(如ASUS TUF系列)需要在BIOS的"Advanced→System Agent Configuration"中手动开启VT-d,否则后续步骤会失败。
2. 宿主机环境配置:内核与驱动的交响曲
2.1 安装必要软件包
sudo apt update && sudo apt install -y \ qemu-kvm libvirt-daemon-system virt-manager \ ovmf libguestfs-tools cpu-checker验证KVM是否可用:
kvm-ok # 应显示"KVM acceleration can be used"2.2 配置内核参数
编辑/etc/default/grub,找到GRUB_CMDLINE_LINUX行:
GRUB_CMDLINE_LINUX="... intel_iommu=on iommu=pt video=efifb:off"对于AMD平台,改为:
GRUB_CMDLINE_LINUX="... amd_iommu=on iommu=pt video=efifb:off"更新grub并重启:
sudo update-grub && sudo reboot2.3 验证IOMMU分组
重启后执行:
dmesg | grep -e DMAR -e IOMMU正常应看到"DMAR: IOMMU enabled"。再检查设备分组:
#!/bin/bash shopt -s nullglob for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do echo "IOMMU Group ${g##*/}:" for d in $g/devices/*; do echo -e "\t$(lspci -nns ${d##*/})" done done理想情况下,待直通的设备应独占一个IOMMU Group。若与其他设备同组,需要ACS补丁(风险较高,建议换主板)。
3. VFIO驱动绑定:设备接管的关键战役
3.1 定位设备信息
先找出要直通的设备ID:
lspci -nn | grep -E 'VGA|Network'例如输出:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] 02:00.0 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521]3.2 配置VFIO驱动
创建配置文件/etc/modprobe.d/vfio.conf:
options vfio-pci ids=10de:2484,8086:1521然后更新initramfs:
sudo update-initramfs -u3.3 解决NVIDIA驱动冲突
对于NVIDIA显卡,需要禁用nouveau驱动:
echo "blacklist nouveau" | sudo tee /etc/modprobe.d/blacklist-nvidia-nouveau.conf echo "options nouveau modeset=0" | sudo tee -a /etc/modprobe.d/blacklist-nvidia-nouveau.conf4. virt-manager实战:图形化直通全流程
4.1 创建虚拟机注意事项
- 选择"自定义安装"→"Q35"芯片组
- 固件选择UEFI(OVMF)
- CPU模式设为"host-passthrough"
- 添加PCI设备时勾选"所有功能"
4.2 解决常见问题
- 宿主机黑屏:在虚拟机XML中添加:
<qemu:commandline> <qemu:arg value='-set'/> <qemu:arg value='device.hostdev0.x-pci-sub-vendor-id=0x1234'/> <qemu:arg value='-set'/> <qemu:arg value='device.hostdev0.x-pci-sub-device-id=0x5678'/> </qemu:commandline> - Error 43(NVIDIA显卡):添加hidden state和kvm=off:
<features> <kvm> <hidden state='on'/> </kvm> </features>
5. 性能调优与监控
5.1 CPU拓扑优化
virsh edit 虚拟机名称在 部分添加:
<topology sockets='1' dies='1' cores='8' threads='2'/>5.2 网络性能对比测试
使用iperf3测试直通网卡与虚拟网卡的差异:
| 测试项 | 虚拟网卡(virtio) | 直通网卡(SR-IOV) |
|---|---|---|
| 吞吐量(Gbps) | 3.2 | 9.8 |
| 延迟(μs) | 120 | 28 |
| CPU占用率(%) | 45 | 5 |
5.3 GPU压力测试
glmark2 --fullscreen # 图形性能测试 nvidia-smi -q # 查看GPU状态6. 高级技巧:多设备直通与热插拔
对于需要频繁更换直通设备的场景,可以配置libvirt规则:
<hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </source> <alias name='hostdev0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </hostdev>实际项目中,我发现将USB控制器直通给Windows虚拟机后,外设响应速度明显提升。但要注意避免将宿主机正在使用的USB根集线器直通,否则会导致键鼠失灵。
