起因是,我想搭建一个「真•All In One主机」,又能拿来远程串流游戏,同时又想着跑其他业务,比如转码之类的
于是就想:显卡能不能像CPU内存一样也能虚拟化,分给不同的主机?答案显然是可以的,只不过太折腾了。
原理
其实Nvidia针对Quadro\Tesla等系列服务器显卡是可以开启虚拟化GPU功能的 官网介绍
只不过是在GeForce系列消费卡上禁用了该功能,我家里只有一张 2070 Super,显然不折腾一下是玩不了的
所以对例如我这种特殊的需求,有大佬开发了 nvidia-vgpu 项目来解锁这个限制,例如:vGPU-Unlock-patcher
搭建
主板开启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下就可以关闭掉虚拟机的显示硬件,彻底使用远程软件控制虚拟机