记录一下ProxmoxVE下使用Nvidia家用消费级显卡开启vGPU搭建云主机一例

Linux, Windows, 折腾 2024/03/13

起因是,我想搭建一个「真•All In One主机」,又能拿来远程串流游戏,同时又想着跑其他业务,比如转码之类的

于是就想:显卡能不能像CPU内存一样也能虚拟化,分给不同的主机?答案显然是可以的,只不过太折腾了。

原理

其实Nvidia针对Quadro\Tesla等系列服务器显卡是可以开启虚拟化GPU功能的  官网介绍

只不过是在GeForce系列消费卡上禁用了该功能,我家里只有一张 2070 Super,显然不折腾一下是玩不了的

所以对例如我这种特殊的需求,有大佬开发了 nvidia-vgpu 项目来解锁这个限制,例如:vGPU-Unlock-patcher

限制

30系及往后均不支持,手握30或40系的朋友就不折腾了~

以下型号的消费级显卡均支持vGPU

Maxwell 架构:(GTX 9xx、Quadro Mxxxx、Tesla Mxx),GTX 970 除外

Pascal 架构 :(GTX 10xx、Quadro Pxxxx、Tesla Pxx)

Turing 架构 :(GTX 16xx、RTX 20xx、Txxxx)

搭建

主板开启IOMMU、VT-d(Intel)、SVM(AMD)等,然后PVE的搭建就略了,我用的版本是 PVE 8.1,Linux 6.5.13

换源

sed -i 's|^deb http://ftp.debian.org|deb https://mirrors.ustc.edu.cn|g' /etc/apt/sources.list
sed -i 's|^deb http://security.debian.org|deb https://mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.list
source /etc/os-release
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/pve $VERSION_CODENAME pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list

更新包、安装依赖

apt update
apt install build-essential dkms mdevctl pve-headers-$(uname -r)

开启直通

编辑 /etc/default/grub ,并修改 GRUB_CMDLINE_LINUX_DEFAULT 一行

#Intel主板
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt initcall_blacklist=sysfb_init pcie_acs_override=downstream"

#AMD
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt initcall_blacklist=sysfb_init pcie_acs_override=downstream"

修改配置

#加载所需内核模块
echo vfio >> /etc/modules
echo vfio_iommu_type1 >> /etc/modules
echo vfio_pci >> /etc/modules
echo vfio_virqfd >> /etc/modules
#屏蔽驱动
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
#忽略显卡警告(虚拟Win下使用N卡时需要)
echo "options kvm ignore_msrs=1" > /etc/modprobe.d/kvm.conf

更新内核并重启

update-initramfs -k all -u
reboot

验证

验证是否启用IOMMU

dmesg | grep -e DMAR -e IOMMU

例如我是AMD的主板,参考返回值为

pci 0000:00:00.2: AMD-Vi: IOMMU performance counters supported
pci 0000:00:00.2: AMD-Vi: Found IOMMU cap 0x40

验证是否启用IOMMU中断重映射

dmesg | grep remapping

参考返回值为

x2apic: IRQ remapping doesn't support X2APIC mode
AMD-Vi: Interrupt remapping enabled

宿主机安装驱动

首先需要给宿主机安装绕开限制的驱动,可以用我提供的,也可以自行按照vGPU-Unlock-patcher的教程制作

下载:https://www.alipan.com/s/2tMivgLTWxh

NVIDIA-Linux-x86_64-535.129.03-vgpu-kvm-patched.run(已打过解锁补丁),上传至PVE下

chmod +x NVIDIA-Linux-x86_64-535.129.03-vgpu-kvm-patched.run
./NVIDIA-Linux-x86_64-535.129.03-vgpu-kvm-patched.run

一路 yes 即可

驱动安装完成后,先重新启动一下相关服务,看看有没有报错,有报错根据报错分析解决

systemctl restart nvidia-vgpud.service
systemctl restart nvidia-vgpu-mgr.service

然后接着验证显卡是否识别

nvidia-smi

接着验证所有生成虚拟显卡

mdevctl types | grep Name

创建虚拟机

常规选项

显卡:选择 标准VGA (随便选,后面要改)

机型:选择 q35

BIOS 选择 OVMF(UEFI) 

CPU:选择 host

内存:关闭Ballooning设备

这个时候先别急着添加PCIE设备(虚拟显卡),先插电开机

安装远程软件

为啥先装远程软件,因为这里有个坑

我直接添加的虚拟显卡,然后进系统装驱动,装完后发现,PVE里的控制台(VNC)只显示了任务栏,桌面啥也没有

排查半天不知道问题在哪,反反复复的搞了好几次

原来是,当给虚拟机显卡打上驱动后,就会多出来一个桌面

我在控制台看到的只是副屏,没法操作,而且还没法更改主副屏,只能重装再来一次

大概就是这样

所以要先安装任意远程软件,Todesk、Parsec等都可以,注意Windows自带的RDP远程桌面无法直接修改主副屏设置

安装完后关闭虚拟机,开始添加虚拟显卡

添加虚拟显卡

添加PCIE设备,先勾选 原始设备,选择本机物理显卡

然后在 MDev类型 中选择需要的虚拟显卡

下图红框中,选择 型号尾部带Q 的,framebuffer为显存大小,根据需求自行选择

我这里显示的是RTX6000,是因为我安装的驱动将2070s模拟成rtx6000以绕过限制

开启虚拟机

安装驱动

官网下的常规的 desktop版 驱动是没法安装的,只能安装 GRID驱动

另外,虚拟机的驱动版本要低于宿主机的

下载:https://www.alipan.com/s/2tMivgLTWxh

安装 528.24_grid_win10_win11_server2019_server2022_dch_64bit_international.exe 即可

虚拟机安装完驱动还需要进行最后一步

获取授权

前文讲到,N卡的vGPU技术是需要授权解锁的,即便客户机安装了驱动,也是需要获取授权才能正常使用的

所以又有大佬开发了一个简单易用的工具 FastAPI-DLS,原理是通过模拟正规流程的激活服务器,对虚拟机进行许可证授权,最主要是它支持Docker部署

模拟获取授权的方式有很多种,这里推荐 FastAPI-DLS

搭建授权服务

需要一台安装了openssl和docker的服务器,本地虚拟一个也可以

准备

模拟授权的服务器需要以https运行,所以需要先生成证书

#创建证书目录
WORKING_DIR=/var/fastapi-dls-cert
mkdir -p $WORKING_DIR
cd $CERT_DIR
#创建密钥
openssl genrsa -out $WORKING_DIR/private.pem 2048
openssl rsa -in $WORKING_DIR/private.pem -outform PEM -pubout -out $WORKING_DIR/public.pem
#创建证书
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout $WORKING_DIR/webserver.key -out $WORKING_DIR/webserver.crt

创建容器

命令中两处参数需要修改

DLS_URL=192.168.3.200 这里修改为搭建授权服务的服务器地址

-p 33443:443

我的授权Docker是搭在群晖下的,HTTPS默认端口443已占用,为避免和其他服务冲突,我将443映射到33443

docker run -e DLS_URL=192.168.3.200 -e DLS_PORT=443 -p 33443:443 -v $WORKING_DIR:/app/cert -v dls-db:/app/database collinwebdesigns/fastapi-dls:latest

获取授权

进入虚拟机,使用管理员权限的Powershell执行

#获取证书并保存到本地
curl.exe --insecure -L -X GET https://<dls-hostname-or-ip>/-/client-token -o "C:\Program Files\NVIDIA Corporation\vGPU Licensing\ClientConfigToken\client_configuration_token_$($(Get-Date).tostring('dd-MM-yy-hh-mm-ss')).tok"
#重启NV相关服务
Restart-Service NVDisplay.ContainerLocalSystem

验证授权

nvidia-smi.exe -q | Select-String License

至此,就可以畅快玩耍了

尾巴

1.用远程软件进入桌面,修改显示器只在显示屏1或2上,就能关闭主副屏幕的干扰

然后在PVE下就可以关闭掉虚拟机的显示硬件,彻底使用远程软件控制虚拟机

2.原神

本文标签:


5 条评论

  • blacktail 评论于 回复

    那虚拟机linux也可以用这个vGPU咯

    • Bug侠 评论于 回复

      @blacktail
      必须可以

  • vgpu苦手 评论于 回复

    你好 这个教程特别有用 感谢 但我还是卡在最后的最后
    我所有的流程都走完了,包括win11 vm上安装guest driver也成功,无论pve还是windows vm都显示正常 parsec也能正常hardware encoding。我用的是535的host driver,528的guest driver。
    但只要我重启windows vm,vm就会挂。表现是直接蓝屏然后自动重启, 或是启动了但novnc卡住+parsec无法检测
    请问你有遇到过这个问题吗?

    • Bug侠 评论于 回复

      @vgpu苦手
      不好意思,我至今也没有这个问题,只能是慢慢排查了,比如换Win10、修改虚拟显卡类型等等

  • cyberWalker 评论于 回复

    学习到了,正好以后用得上,谢谢分享

  • 评论(本站已开启评论回复邮件通知功能,请如实填写邮箱以便及时收到回复)