在 Proxmox VE (PVE) 8.0 环境下,将 NVIDIA 显卡直通给 KVM 虚拟机(Windows/Linux)或实现 vGPU 分流,是搭建高性能家用服务器、云游戏主机或 AI 绘图环境的常见需求。PVE 8.0 采用了较新的 Linux 6.2 内核,这在带来新特性的同时也让不少旧版的直通教程失效。
本文将彻底梳理 PVE 8.0 下 NVIDIA 显卡直通的完整链路,并重点解决 Windows 虚拟机中的 Code 43 报错(驱动无法加载) 以及 vGPU 授权(利用 fastapi-dls 激活) 的核心痛点。
第一阶段:PVE 8.0 宿主机底层准备
显卡直通的第一步是让宿主机(PVE)“放手”该显卡,将其完全托管给 VFIO 驱动。
1. 开启 IOMMU 支持
首先需要确定主板 BIOS/UEFI 中已经开启了 Intel Virtualization Technology (VT-d) 或 AMD SVM/IOMMU。
接着修改 PVE 的内核引导参数。PVE 8.0 默认使用 systemd-boot(UEFI 引导)或 GRUB(Legacy 引导)。我们需要先确认当前的引导方式:
# 执行此命令,如果有输出则为 systemd-boot,否则为 GRUB
bootctl status
情况 A:如果是 GRUB 引导
编辑 /etc/default/grub 文件:
nano /etc/default/grub
找到 GRUB_CMDLINE_LINUX_DEFAULT 这一行,根据 CPU 类型修改:
- Intel CPU:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt initcall_blacklist=sysfb_init" - AMD CPU:
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt initcall_blacklist=sysfb_init"
注意:
initcall_blacklist=sysfb_init是 PVE 8.0(Linux 6.x 内核)解决直通后宿主机画面冻结、显卡被抢占的关键参数。
保存后更新 GRUB:
update-grub
情况 B:如果是 systemd-boot 引导
编辑 /etc/kernel/cmdline 文件(该文件只有一行):
nano /etc/kernel/cmdline
在末尾追加对应的参数(以 Intel 为例):
root=ZFS=rpool/ROOT/pve-1 boot=zfs intel_iommu=on iommu=pt initcall_blacklist=sysfb_init
保存后刷新引导配置:
proxmox-boot-tool refresh
2. 加载 VFIO 模块
编辑 /etc/modules,追加以下四行,确保内核启动时加载虚拟化通道驱动:
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
3. 屏蔽开源及官方显卡驱动(防止宿主机抢占)
为了防止 PVE 宿主机自己加载 NVIDIA 驱动,必须建立黑名单。
编辑 /etc/modprobe.d/blacklist.conf:
nano /etc/modprobe.d/blacklist.conf
写入以下内容:
blacklist nouveau
blacklist nvidia
blacklist nvidiafb
blacklist radeon
4. 将显卡绑定至 vfio-pci
通过 lspci -nn | grep -i nvidia 查看显卡的 PCI 设备 ID。例如:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA106 [GeForce RTX 3060] [10de:2503] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GA106 High Definition Audio Controller [10de:228e] (rev a1)
这里的 10de:2503 和 10de:228e 就是我们要绑定的硬件 ID。
编辑 /etc/modprobe.d/vfio.conf:
nano /etc/modprobe.d/vfio.conf
写入:
options vfio-pci ids=10de:2503,10de:228e disable_vga=1
(请将上述 ID 替换为您自己显卡和对应 HDMI 音频的 ID)
最后,应用上述更改并重启 PVE 宿主机:
update-initramfs -u -k all
reboot
重启后,执行 lspci -nnk -s 01:00,若看到 Kernel driver in use: vfio-pci,说明宿主机端直通配置成功。
第二阶段:虚拟机配置与 Code 43 完美避坑
在 Windows 虚拟机直通显卡后,经常会在设备管理器中看到显卡打着黄色感叹号,提示 “该设备已被停止 (Code 43)”。这是因为 NVIDIA 驱动检测到了虚拟化环境(尽管现在消费级显卡驱动已放宽限制,但在特定硬件拓扑下仍会触发保护)。
1. 创建虚拟机 (VM) 的正确姿势
- 系统: 建议选择 Windows 10/11,类别选择
Microsoft Windows。 - 机型 (Machine): 强烈建议选择
q35。 - BIOS: 必须选择
OVMF (UEFI)。同时添加 EFI 磁盘。 - CPU: 类别(Type)必须选择
host。
2. 添加 PCI 设备
在虚拟机的“硬件”选项中,添加 PCI Device:
- 选择您的 NVIDIA 显卡(例如
0000:01:00.0)。 - 勾选 All Functions(确保显卡和音频一并直通)。
- 勾选 ROM-Bar。
- 勾选 PCI-Express。
- 如果这是虚拟机唯一的显卡,且需要物理输出,可以勾选 Primary GPU(主 GPU)。
3. 修改 VM 配置文件(消灭 Code 43 的关键)
在 PVE 网页端配置完后,不要急于开机。我们需要登录 PVE 命令行,直接修改虚拟机的配置文件。
假设您的虚拟机 VMID 是 101:
nano /etc/pve/qemu-server/101.conf
在文件顶部或适当位置,修改/添加以下参数:
欺骗 CPU 虚拟化信号:
将cpu: host改为:cpu: host,hidden=1,flags=+pcid(这会向 guest 隐藏 KVM 虚拟化标志)
注入伪造的硬件厂商标识:
在文件中添加一行args参数:args: -cpu 'host,hv_vendor_id=genuineIntel,kvm=off'(如果是 AMD 平台,可以写
hv_vendor_id=AuthenticAMD。此项操作能彻底屏蔽 NVIDIA 驱动对 hypervisor 的检测)
保存并退出。现在启动虚拟机,安装官方 NVIDIA 驱动,Code 43 报错通常会彻底消失,显卡能正常工作。
第三阶段:NVIDIA vGPU 部署与 DLS 授权激活
如果您不满足于将整张显卡给一台虚拟机,而是希望通过 vGPU 将一张显卡切片分给多台虚拟机共同使用(如 Tesla P4/T4/A10,或者通过 vgpu_unlock 破解的消费级显卡),那么就必须解决 vGPU 的授权问题。
在没有授权的情况下,vGPU 运行 20 分钟后会锁定帧率(通常降到 3 FPS 或限制分辨率),使其完全无法使用。
1. 搭建 fastapi-dls 授权服务器
目前最主流、最稳定的本地授权解决方案是使用基于 Docker 的开源项目 fastapi-dls。
在一台通网的 Linux 虚拟机或直接在 PVE 宿主机上,使用 Docker 部署该授权服务。
# 创建存储证书的目录
mkdir -p /opt/fastapi-dls/cert
cd /opt/fastapi-dls/cert
# 生成自签名证书(服务运行必需)
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
# 运行 Docker 容器 (将 443 端口映射至宿主机的某个空闲端口,如 8443)
docker run -d --name fastapi-dls \
-p 8443:443 \
-v /opt/fastapi-dls/cert:/app/cert \
-e DLS_URL=192.168.1.100 \
-e DLS_PORT=8443 \
--restart always \
collinwebstore/fastapi-dls:latest
(请将 192.168.1.100 替换为运行该 Docker 容器的实际 IP)
部署完成后,在浏览器中访问 https://192.168.1.100:8443,如果能正常打开且显示 API 页面,说明授权服务器部署成功。
2. 虚拟机客户端激活授权
在虚拟机内安装好对应的 NVIDIA vGPU 驱动后,我们需要让客户端向刚才搭建的 fastapi-dls 服务器请求授权。
Windows 客户端激活:
- 在 Windows 虚拟机中,使用管理员权限打开 PowerShell。
- 确保系统可以信任自签名证书,运行以下命令(请替换 IP 和端口):
# 允许 PowerShell 执行脚本 Set-ExecutionPolicy Bypass -Scope Process -Force # 下载并运行激活脚本 [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri "https://192.168.1.100:8443/client-token" -OutFile "$env:TEMP\client_configuration_token.tok" -SkipCertificateCheck # 将 Token 移动至 NVIDIA 对应的目录 Copy-Item "$env:TEMP\client_configuration_token.tok" -Destination "C:\ProgramGrid\NVIDIA Corporation\Grid-Licensing\" -Force - 重启 NVIDIA Display Container LS 服务:
Restart-Service -Name "NVDisplay.ContainerLocalSystem"
Linux 客户端 (如 Ubuntu) 激活:
- 登录 Linux 虚拟机,下载授权 Token 文件:
curl --insecure -L -X GET https://192.168.1.100:8443/client-token -o /etc/nvidia/ClientConfigToken/client_configuration_token.tok - 赋予该文件正确的读取权限:
chmod 744 /etc/nvidia/ClientConfigToken/client_configuration_token.tok - 重启 NVIDIA 拓扑服务以应用授权:
systemctl restart nvidia-gridd.service
3. 验证授权状态
- Windows: 打开 NVIDIA 控制面板,如果左侧导航栏出现“管理许可证”选项,且状态显示为 “您的系统已获取 GRID 虚拟 GPU 许可”(Your system is licensed for GRID vGPU),说明激活成功。
- Linux: 执行
nvidia-smi -q | grep License,如果看到License Status: Licensed,则代表授权顺利完成。
通过以上三步的深度调整,您即可在 PVE 8.0 下获得极其稳定、高性能且免受授权到期困扰的 NVIDIA 虚拟化硬件环境。