HOOOS

PVE 8.0 NVIDIA 独显直通与 vGPU 全攻略:从底层硬件到完美解决 Code 43 与授权痛点

0 16 极客折腾帝 Proxmox VE显卡直通
Apple

在 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:250310de: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

  1. 选择您的 NVIDIA 显卡(例如 0000:01:00.0)。
  2. 勾选 All Functions(确保显卡和音频一并直通)。
  3. 勾选 ROM-Bar
  4. 勾选 PCI-Express
  5. 如果这是虚拟机唯一的显卡,且需要物理输出,可以勾选 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 客户端激活:

  1. 在 Windows 虚拟机中,使用管理员权限打开 PowerShell。
  2. 确保系统可以信任自签名证书,运行以下命令(请替换 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
    
  3. 重启 NVIDIA Display Container LS 服务:
    Restart-Service -Name "NVDisplay.ContainerLocalSystem"
    

Linux 客户端 (如 Ubuntu) 激活:

  1. 登录 Linux 虚拟机,下载授权 Token 文件:
    curl --insecure -L -X GET https://192.168.1.100:8443/client-token -o /etc/nvidia/ClientConfigToken/client_configuration_token.tok
    
  2. 赋予该文件正确的读取权限:
    chmod 744 /etc/nvidia/ClientConfigToken/client_configuration_token.tok
    
  3. 重启 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 虚拟化硬件环境。

点评评价

captcha
健康