2023年7月

前言

接上文,本文将讲述如何在Ubuntu 22.04.2 LTS上配置Sunshine云桌面环境

安装Ubuntu

虚拟机配置同上文,为了方便安装NVIDIA驱动,同样不启用安全启动

这里选择最简单的ext4分区:

截屏2023-07-21 09.17.20

配置用户时,勾选自动登录,原因详见上文:

截屏2023-07-21 09.18.49

安装GRID驱动

确保系统最新

sudo apt update
sudo apt upgrade

如果升级了内核,则需重启

reboot

安装依赖

sudo apt install linux-headers-$(uname -r) gcc make dkms libglvnd-core-dev libglvnd0 libglvnd-dev

禁用nouveau驱动

echo "blacklist nouveau" >> /etc/modprobe.d/blacklist-nouveau.conf

更新initramfs

sudo update-initramfs -u -k all

重启到多用户模式

sudo systemctl set-default multi-user.target
reboot

安装GRID驱动

sudo -i
chmod +x ./NVIDIA-Linux-x86_64-535.54.03-grid.run
./NVIDIA-Linux-x86_64-535.54.03-grid.run

截屏2023-07-21 09.52.42

弹出建议使用软件源安装的提示,选择继续安装

截屏2023-07-20 16.33.03

安装32位兼容库

截屏2023-07-20 16.34.12

注册为DKMS模块,这样内核更新后驱动会重新编译以自动适配新内核

截屏2023-07-20 16.36.00

我们需要手动生成X配置文件,选择No

重启到图形模式

sudo systemctl set-default graphical.target
reboot

激活vGPU许可

sudo curl --insecure -X GET https://<fastapi-dls-ip>/client-token -o /etc/nvidia/ClientConfigToken/client_configuration_token.tok
sudo systemctl restart nvidia-gridd

可以执行以下命令查看是否生效:

rickg@clouddesktop:~$ nvidia-smi -q | grep "License"
    vGPU Software Licensed Product
        License Status                    : Licensed (Expiry: 2028-7-19 2:7:2 GMT)

安装Sunshine

下载&安装

前往GitHub Release页面下载Sunshine

{% link https://github.com/LizardByte/Sunshine/releases/ %}

sudo apt install ./sunshine-ubuntu-22.04-amd64.deb

添加udev规则

Sunshine需要uinput的权限才能创建鼠标和虚拟手柄事件

echo 'KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"' | \
sudo tee /etc/udev/rules.d/85-sunshine.rules

随后重启

reboot

配置GDM & Xorg

GDM

编辑/etc/gdm3/custom.conf,去除WaylandEnable=false的注释:

# GDM configuration storage
#
# See /usr/share/gdm/gdm.schemas for a list of available options.

[daemon]
AutomaticLoginEnable=true
AutomaticLogin=rickg

# Uncomment the line below to force the login screen to use Xorg
WaylandEnable=false

# Enabling automatic login

# Enabling timed login
#  TimedLoginEnable = true
#  TimedLogin = user1
#  TimedLoginDelay = 10

[security]

[xdmcp]

[chooser]

[debug]
# Uncomment the line below to turn on debugging
# More verbose logs
# Additionally lets the X server dump core if it crashes
#Enable=true

Xorg

编辑/etc/X11/xorg.conf

Section "ServerLayout"
    Identifier     "Layout0"
    Screen      0  "Screen0"
EndSection

Section "Monitor"
    Identifier     "Monitor0"
EndSection

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BoardName      "GRID P40-8Q"
    BusID          "PCI:1:0:0"
EndSection

Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection

BoardName即GPU型号,BusID根据实际情况来,执行lspci | grep VGA

rickg@clouddesktop:~$ lspci | grep VGA
00:01.0 VGA compatible controller: Device 1234:1111 (rev 02)
01:00.0 VGA compatible controller: NVIDIA Corporation GP102GL [Tesla P40] (rev a1)

可以看到vGPU的ID是01:00.0,BusID则为"PCI:1:0:0"

连接到VM

重启VM,ssh连接到VM,启动Sunshine服务:

systemctl enable --now --user sunshine

访问https://<vm-ip>:47990/,进入WebUI

截屏2023-07-20 17.20.36

首次配置用户名密码

截屏2023-07-21 10.28.12

可以看到启用了NVENC硬件编码和NVFBC捕获

打开Moonlight,连接,配对,云桌面就在眼前:

截屏2023-07-21 10.32.11

参考资料

Install NVIDIA Drivers on Debian / Ubuntu / Linux Mint / LMDE :: If Not True Then False (if-not-true-then-false.com)

Sunshine documentation (lizardbyte.dev)

前言

这是云桌面的第三篇,Windows云电脑大家听过很多,可你有曾想过,Linux搭配Desktop Environment也能打造云电脑,本文将介绍如何在Fedora 38上使用Sunshine搭建云桌面服务。

虚拟机配置

虚拟机配置如下,hostpci0为P40 vGPU,mDev型号为GRID-P40-8Q,hostpci1为82599 SR-IOV网卡,由于需要安装NVIDIA驱动,创建EFI磁盘时不勾选预注册密钥一项。

截屏2023-07-20 15.06.23

安装Fedora

从ISO启动,因为这是虚拟镜像,选择Install Fedora 38

截屏2023-07-20 15.13.56

选择语言后继续,配置安装源,如图所示,这里使用清华源

截屏2023-07-20 15.17.09

选择软件,这里我选择Fedora Workstation,如果喜欢别的DE也可以选择其他的

截屏2023-07-20 15.18.34

进行分区,这里使用Btrfs分区

添加一个300M分区,挂载点/boot/efi

截屏2023-07-20 15.22.37

添加Swap(可选)

添加Btrfs卷,大小为剩下的所有,名称为@,如图所示

截屏2023-07-20 15.25.58

数据中添加/home挂载点,名称为@home,如图所示

截屏2023-07-20 15.27.41

随后开始安装,喝杯☕️吧!

安装NVIDIA GRID驱动

{% note color:green 提示 本文所用驱动为GRID 16.0,版本为535.54.03 %}

确保系统最新

sudo dnf update

如果升级了内核,需要重启

reboot

安装依赖

sudo dnf install kernel-devel kernel-headers gcc make dkms acpid libglvnd-glx libglvnd-opengl libglvnd-devel pkgconfig

禁用nouveau

nouveau是开源nvidia驱动,它与grid驱动冲突,必须禁用它

编辑/etc/modprobe.d/blacklist-nouveau.conf

blacklist nouveau

编辑/etc/default/grub

GRUB_CMDLINE_LINUX=”…”中添加rd.driver.blacklist=nouveaunvidia-drm.modeset=1,如下所示:

GRUB_CMDLINE_LINUX="rhgb quiet rd.driver.blacklist=nouveau nvidia-drm.modeset=1"

更新grub配置:

sudo grub2-mkconfig -o /boot/grub2/grub.cfg

删除nouveau驱动:

sudo dnf remove xorg-x11-drv-nouveau

备份旧initramfs:

sudo mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r)-nouveau.img

生成initramfs:

sudo dracut /boot/initramfs-$(uname -r).img $(uname -r)

重启到多用户模式

sudo systemctl set-default multi-user.target
reboot

安装驱动

sudo -i
chmod +x ./NVIDIA-Linux-x86_64-535.54.03-grid.run
./NVIDIA-Linux-x86_64-535.54.03-grid.run

截屏2023-07-20 16.33.03

安装32位兼容库

截屏2023-07-20 16.34.12

注册为DKMS模块,这样内核更新后驱动会重新编译以自动适配新内核

截屏2023-07-20 16.36.00

我们需要手动生成X配置文件,选择No

重启到图形模式

sudo systemctl set-default graphical.target
reboot

激活vGPU许可

sudo curl --insecure -X GET https://<fastapi-dls-ip>/client-token -o /etc/nvidia/ClientConfigToken/client_configuration_token.tok
sudo systemctl restart nvidia-gridd

可以执行以下命令查看是否生效:

[rickg@clouddesktop ~]$ nvidia-smi -q | grep "License"
    vGPU Software Licensed Product
        License Status                    : Licensed (Expiry: 2028-7-18 9:24:33 GMT)

安装Sunshine

添加rpmfusion

sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \
https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm

安装Sunshine

前往GitHub Release页面下载Sunshine

{% link https://github.com/LizardByte/Sunshine/releases/ %}

sudo dnf install ./sunshine-fedora-38-amd64.rpm

添加udev规则

Sunshine需要uinput的权限才能创建鼠标和虚拟手柄事件

echo 'KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"' | \
sudo tee /etc/udev/rules.d/85-sunshine.rules

随后重启

reboot

配置GDM

由于X的权限问题,以用户身份运行的Sunshine无法访问GDM登录界面,因此需要配置GDM自动登录。

[root@clouddesktop ~]$ xrandr --display :0
Authorization required, but no authorization protocol specified. Can't open display :0

禁用Wayland

笔者需要自定义X配置文件,而GDM默认在Wayland上运行,因此需要禁用Wayland,使GDM在Xorg上运行。

编辑/etc/gdm/custom.conf,去除WaylandEnable=false的注释:

# GDM configuration storage

[daemon]
# Uncomment the line below to force the login screen to use Xorg
WaylandEnable=false

[security]

[xdmcp]

[chooser]

[debug]
# Uncomment the line below to turn on debugging
#Enable=true

配置自动登录

[daemon]下添加AutomaticLoginEnable=trueAutomaticLogin=user,其中user为用户名:

# GDM configuration storage

[daemon]
# Uncomment the line below to force the login screen to use Xorg
WaylandEnable=false
AutomaticLoginEnable=true
AutomaticLogin=rickg

[security]

[xdmcp]

[chooser]

[debug]
# Uncomment the line below to turn on debugging
#Enable=true

配置Xorg

编辑/etc/X11/xorg.conf

Section "ServerLayout"
    Identifier     "Layout0"
    Screen      0  "Screen0"
EndSection

Section "Monitor"
    Identifier     "Monitor0"
EndSection

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BoardName      "GRID P40-8Q"
    BusID          "PCI:1:0:0"
EndSection

Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection

BoardName即GPU型号,BusID根据实际情况来,执行lspci | grep VGA

[rickg@clouddesktop ~]$ lspci | grep VGA
00:01.0 VGA compatible controller: Device 1234:1111 (rev 02)
01:00.0 VGA compatible controller: NVIDIA Corporation GP102GL [Tesla P40] (rev a1)

可以看到vGPU的ID是01:00.0,BusID则为"PCI:1:0:0"

连接到VM

重启VM,可以看到PVE VNC端画面定在了开机画面的最后,这是因为输出已经指向vGPU内建的虚拟显示器

SSH连接到VM,启动Sunshine服务

systemctl enable --now --user sunshine

访问https://<vm-ip>:47990/,进入WebUI

截屏2023-07-20 17.20.36

首次配置用户名密码

截屏2023-07-20 17.49.20

可以看到启用了NVENC硬件编码

打开Moonlight,连接,配对,云桌面就在眼前:

截屏2023-07-20 18.00.43

可以看到GPU是在工作的:

截屏2023-07-20 18.02.59

如果网络环境好的话,云桌面体验下来还是非常流畅的

参考资料

Fedora 38/37/36 NVIDIA Drivers Install Guide :: If Not True Then False (if-not-true-then-false.com)

GDM - ArchWiki (archlinux.org)

Sunshine documentation (lizardbyte.dev)

前言

上文笔者配置好了vGPU相关,那么本文笔者将创建一个简单的Windows云桌面。

方案

对于云桌面,不谈那些高大上的企业级方案,毕竟搞到了也没有授权(

既然说“简单”,那来讲讲以下几个简单的方案吧:

  • SPICE
  • VNC
  • Parsec
  • Moonlight + Sunshine

SPICE

可以说是最快捷的方案了,直接被Proxmox VE所集成,甚至VM在安装QXL驱动之后还能拥有简单的3D功能(前提要Windows 8.1以上

缺点也很明显,有点卡,只支持Windows、Linux、Mac(Mac甚至要自己编译

QXL羸弱的图形性能,跑3D应用是别想了

PVE里面有个SPICE增强,里面可以开启Video Streaming,个人认为也就是所谓的串流,但感觉开启了也没什么效果。

不过对于轻度使用和没有vGPU的情况,SPICE倒是不错的方案(毕竟不需要在VM上装VNC Server什么的,并且支持剪贴板共享

VNC

VNC(Virtual Network Computing)是一种图形桌面共享系统,使用RFB(远程帧缓冲)协议来提供远程控制功能。在云桌面应用中,VNC可以用来实现对远程虚拟机的访问和管理。

VNC的优点在于跨平台,其客户端非常之多,安全性也较高,同时也支持剪贴板共享

缺点在于,貌似也不支持GPU加速(如有知道的大佬请在评论区指正

串流

最棒的方案,但是对于网络和硬件要求也最苛刻

你需要有一块支持编解码的GPU,以及较高的网络上行带宽

{% link https://www.bilibili.com/read/cv11681088 %}

这里介绍两种:Parsec、Moonlight

Parsec是付费软件,但有免费版本,只不过少了无头显示,4:4:4颜色模式等功能。

Moonlight则完全免费、开源,配合Sunshine使用可以实现4K HDR云游戏(如果条件符合的话)

对于网络,Parsec支持P2P连接 & IPv6,而Moonlight + Sunshine需要手动配置端口转发(不支持IPv6

虚拟机配置

截屏2023-07-19 08.58.23

包含一块NVIDIA vGPU,mDev类型为nvidia-52,对于vGPU类型,见上一篇文章

截屏2023-07-19 08.52.34

配置SPICE

SPICE基本不需要配置,只需要安装spice-guest-tools即可

下载spice-guest-tools

{% link https://www.spice-space.org/download/windows/spice-guest-tools/spice-guest-tools-latest.exe %}

截屏2023-07-19 09.06.04

同意许可协议

截屏2023-07-19 09.06.38

同意安装驱动

截屏2023-07-19 09.07.27

安装完成

登录Proxmox VE,点击VM,点击控制台,下载pve-spice.vv文件

截屏2023-07-19 09.10.43

下载virt-viewer并安装

{% link https://releases.pagure.org/virt-viewer/virt-viewer-x64-11.0-1.0.msi %}

对于Linux,执行以下命令

# Fedora
sudo dnf install virt-manager
# Ubuntu & Debian
sudo apt install virt-manager

打开pve-spice.vv,可以看到VM画面并控制VM

截屏2023-07-19 09.18.18

配置VNC

下载任意VNC Server软件,这里我使用TightVNC

{% link https://www.tightvnc.com/download.php %}

截屏2023-07-19 09.23.28

同意许可协议

安装方式选择“Custom”,勾选TightVNC Server

截屏2023-07-19 09.24.10

将TightVNC Server注册为系统服务

截屏2023-07-19 09.24.54

安装完成后,会提示是否设置VNC密码,这里设置一个

打开VNC Viewer,这里我使用的是RealVNC Viewer

{% link https://www.realvnc.com/en/connect/download/viewer/ %}

输入VM的IP,回车连接

截屏2023-07-19 09.40.19

提示连接未加密,点击“Continue”继续

截屏2023-07-19 09.40.48

输入密码,点击OK连接

截屏2023-07-19 09.42.44

由于VNC服务器的限制,会话没有声音,如果有需求,建议使用RealVNC Server或者SPICE。

配置Parsec

安装

前往Parsec官网下载Parsec

{% link https://parsec.app/ %}

截屏2023-07-20 08.56.04

平台作为主机作为客户端
Windows
Linux
Mac
Android

安装时务必选择Shared方式安装,这样Parsec会以系统用户权限运行,开机时就自动服务,可以显示登录画面而后手动登录。

截屏2023-07-20 09.05.50

安装完成后弹出登录界面

截屏2023-07-20 09.07.30

Parsec需要联网登录使用,如果是内网环境是使用不了Parsec的

没有账户的,直接点击Sign up注册即可

系统要求

客户端

没有硬性要求硬件解码,但若要有良好体验,则Intel QSV / AMD AMF / NVENC是必须的

对于网络,有IPv6为最好

服务端

服务端要求较为严苛,硬件编解码为必须(即类似NVENC / NVDEC),若没有则会在连接时提示主机不支持硬件编解码

截屏2023-07-20 09.14.17

对于网络,有IPv6为最好,在无IPv6情况下,全锥NAT > 限制NAT > 对称NAT

对称型NAT可能导致无法连接

具体可以参见佛西大佬的教程

配置vGPU授权

由于目前vGPU没有授权,所以是不能编解码的,这是就要用上之前配置好的fastapi-dls项目了

打开https://<fastapi-dis-ip>/,可以看到fastapi-dls的介绍页面

截屏2023-07-20 09.23.04

往下翻,找到这一部分,这就是官方的配置教程:

截屏2023-07-20 09.24.00

下载https://<fastapi-dls-ip>/client-token,保存到C:\Program Files\NVIDIA Corporation\vGPU Licensing\ClientConfigToken目录,而后重启VM或重启NVContainerLocalSystem服务,可以看到获得了vGPU授权:

截屏2023-07-20 09.30.29

参数配置

服务端

参数解释
Hosting Enabled是否运行为服务端
Host Name主机名,请通过Windows设置修改
Resolution分辨率
Bandwidth码率限制
FPS帧率,一般选60
Exclusive Input Mode鼠标独占模式
Display使用的显示器,免费版只能选一个
Audio使用的声卡
Echo cancelling回声消除
Virtual Gamepad Type虚拟手柄类型,有Xbox 360、PS4、PS5三种
Quality质量,有低延迟、平衡、高质量三种
Idle Kick Timer挂机自动踢出

客户端

配置的项目不多,连上服务端后,有以下几个选项

截屏2023-07-20 09.38.21

参数解释
Hide Button隐藏Parsec按钮
Chat聊天,用于多人控制一台服务端时
Windowed窗口模式
Sound On打开声音
Codec编码器
Decoder解码器
Prefer 4:4:4 Color优先4:4:4(需要付费)
Resolution分辨率
Bandwidth Limit码率限制
Constant FPS恒定FPS
Send CTRL+ALT+DEL发送CTRL+ALT+DEL

-800错误解决办法

有时打开Parsec会提示-800错误,无法连接到服务器,此情况一般是登录服务器被运营商屏蔽或是受到其他影响,需要为Parsec配置代理。

打开Parsec,点击Settings,一直往底下拉,找到edit the configuration file directly

截屏2023-07-20 09.48.34

随后打开配置文件,在配置文件中加入以下内容:

app_proxy_address = 127.0.0.1
app_proxy_scheme = http
app_proxy = true
app_proxy_port = 7890

其中7890(端口)和http(代理类型)根据你本地运行的代理软件而定。

配置Sunshine

介绍

Sunshine是一个为Moonlight设计的云游戏服务端,它提供低延迟的云游戏能力,支持用AMD、Intel和Nvidia的GPU进行硬件编码,同时也支持软件编码。您可以从任何设备的Moonlight客户端连接到Sunshine,Sunshine提供了一个网页用户界面,用户可以从浏览器进行配置和客户端配对。可以从本地服务器或任何移动设备进行配对。

官方配置要求

{% note color:green 官方提示 该配置要求仅供参考,请勿按照此表格购买相关硬件 %}

最低配置

类型要求
GPUAMD:VCE 1.0或更高,参见obs-amd hardware support
Intel:兼容,VA-API,参见VAAPI hardware support
Nvidia:支持NVENC的GPU,参见nvenc support matrix
CPUAMD: Ryzen 3 或更高
Intel: Core i3 或更高
RAM4GB +
OSWindows: 10 +(不支持Windows Server)
macOS: 11.7 +
Linux/Debian: 11 (bullseye)
Linux/Fedora: 36 +
Linux/Ubuntu: 20.04 + (focal)
网络服务端:5GHz, 802.11ac
客户端:5GHz, 802.11ac

4K推荐配置

类型要求
GPUAMD: Video Coding Engine 3.1 +
Intel: HD Graphics 510 +
Nvidia: GeForce GTX 1080 +
CPUAMD: Ryzen 5 +
Intel: Core i5 +
网络Host: CAT5e ethernet or better
Client: CAT5e ethernet or better

安装

前往Sunshine的Release页面下载

{% link https://github.com/LizardByte/Sunshine/releases %}

Windows平台下载sunshine-windows-installer.exe即可

截屏2023-07-20 12.44.14

选择组件时,注意勾选Launch on Startup(开机自启动)和Add Firewall Exclude(添加防火墙例外)

配置

安装完成后,访问https://localhost:47990/进入Sunchine配置界面,首次配置需要设置用户名和密码

首先打开Troubleshooting,在Logs处往下拉,若找到Found encoder nvenc: [h264_nvenc, hevc_nvenc],则表明GPU编码工作正常,否则将使用软件编码

截屏2023-07-20 13.23.09

General页

该页面主要配置一些通用选项

名称解释
Sunshine Name主机名,显示在Moonlight连接页面中,若不填为计算机名
Log Level日志等级,默认为Info
Logfile Path日志文件目录,默认为sunshine.log
Origin Web UI Allowed允许哪些网络上的计算机访问WebUI,默认为局域网
UPnP通用即插即用(端口转发),默认为关
Gamepads虚拟游戏手柄,有Xbox 360和PS4,默认为Xbox 360
Ping TimeoutPing 超时,超出此时间则断开连接
Advertised Resolutions and FPSSunshine向客户端发送的建议的分辨率,一些客户端(如Switch客户端)需要此分辨率来确定请求的分辨率是否被支持。不影响实际推流的分辨率。
Map Right Alt key to Windows key将右Alt键映射到Win键,当按Win键没反应时可以使用
Command Preparations配置一个命令列表,这些命令将在运行任何应用程序之前或之后执行。如果任何指定的预备命令失败,应用程序的启动过程将被终止。

Files页

该页面主要配置HTTPS证书和配置文件的目录

名称解释
Private KeyHTTPS私钥,必须为2048 bits
CertHTTPS证书,必须签名为一个2048 bits密钥
State File存储Sunshine当前状态的文件
Apps File存储Sunshine Apps的文件

Input页

该页面主要配置输入相关

名称解释
Home/Guide Button Emulation Timeout游戏手柄Home键模拟超时。如果按住Back/Select按钮的时间达到指定的毫秒数,将会模拟按下Home/Guide按钮。如果设置为小于0的值(默认情况下),按住返回/选择按钮不会模拟按下Home/Guide按钮。
Enable Mouse Input启用鼠标输入
Enable Keyboard Input启用键盘输入
Enable Gamepad Input启用手柄输入
Key Repeat Delay按键重复延迟,单位毫秒
Key Repeat Frequency按键重复频率,即每秒一个键最多按几次

Audio / Video页

该页主要配置音视频相关

名称解释
Audio Sink音频源,建议留空以便自动检测。运行安装目录下的tools\audio-info.exe获取声卡名称。
Virtual Sink虚拟音频源,建议留空以便自动检测
Install Steam Audio Drivers安装Steam音频驱动,如果Steam在服务器上安装,这会自动安装驱动以支持5.1/7.1环绕声并将原有声卡静音
Adapter Name用于捕获的显卡名称,建议留空以便自动检测,该显卡必须连接到显示器且通电。运行安装目录下的tools\dxgi-info.exe获取显卡名称
Output Name连接到该显卡的显示器名称,若留空则使用主显示器,一般配合Adapter Name使用
DwmFlush提升鼠标移动时的捕获平滑度。若遇到和垂直同步相关问题请禁用

Advanced页

该页主要配置高级选项

名称解释
PortSunshine服务使用的端口,留空为47989。关于端口转发相关请往下看
Quantization Parameter量化参数,在不支持CBR(恒定比特率)的设备上使用,更高表示更大的压缩、更差的质量
Minimum Software Encoding Thread Count最小软件编码线程数。稍微增加该值会降低编码效率,但通常为了能够使用更多的CPU核心进行编码,这种权衡是值得的。理想的值是能在您的硬件上可靠地按照您期望的流媒体设置进行编码的最低值。
HEVC SupportHEVC支持。对于软件编码服务端请谨慎考虑。
Force a Specific Encoder强制指定编码器,不建议使用
FEC Percentage每个视频帧中每个数据包的纠错包的百分比。更高的值可以纠正更多的丢包,但代价是增加带宽使用。默认值20是GeForce Experience所使用的值。
Channels频道,一般用于以下场景:1.多个客户端分别从LAN和WAN连接,需要不同的码率。2.解码器需要不同的颜色配置。
Web Manager Credentials FileWeb UI凭据文件,保存用户名和密码(
Origin PIN Allowed要求PIN配对的来源,默认为localhost不需要PIN配对
External IP监听的外部IP,留空为自动检测

配置端口转发

在路由器 / FRP上转发以下端口

端口类型
47984TCP
47989TCP
47998UDP
47999UDP
48000UDP
48002UDP
48010TCP / UDP

连接到Sunshine

前往Moonlight Github Release页面下载Moonlight客户端

{% link https://github.com/moonlight-stream/moonlight-qt/releases %}

安装完成后打开,点击右上角的手动添加计算机,输入IP

截屏2023-07-20 13.59.16

添加后出现计算机,但是现在有锁,需要进行PIN验证,点击计算机图标,弹出对话框

截屏2023-07-20 14.01.15

随后在Sunshine控制面板的PIN页面中输入PIN,建立连接

截屏2023-07-20 14.04.02

点击Desktop,稍等片刻,云桌面就出现在我们眼前了。

截屏2023-07-20 14.06.28

参考资料

SPICE - Proxmox VE

Home (spice-space.org)

Virtual Network Computing - Wikipedia

Moonlight Game Streaming: Play Your PC Games Remotely (moonlight-stream.org)

LizardByte/Sunshine: Self-hosted game stream host for Moonlight. (github.com)

Connect to Work or Games from Anywhere | Parsec

佛西博客 - 人人走向云游戏——Parsec详解 (buduanwang.vip)

前言

随着互联网设施的建设和云计算的发展,“云桌面”、“云游戏”等概念已逐渐走入人们的视线。无论如何,它都改变了我们理解硬件性能和游戏体验的方式。本系列文章将介绍如何使用Proxmox VE构建一个简单的,支持Windows、Linux的云桌面系统。

认识vGPU

要为VM添加图形功能,一般有三种方法:

  • 软件模拟(如“标准VGA”,“VMware SVGA II”)
  • PCI Passthrough
  • vGPU(mDev / sr-IOV)

性能为 PCI Passthrough > vGPU > 软件模拟

对于vGPU,市面上有三种方案:

IntelAMDNVIDIA
GVT-gMxGPUNVIDIA vGPU

笔者采用的是NVIDIA Tesla P40这款GPU,故本文只介绍NVIDIA vGPU。

vGPU架构

从上图可以看出,NVIDIA vGPU的实现由软硬件协同而成,硬件上有GPU,软件上有NVIDIA vGPU Manager。

vGPU支持的显卡

一般情况下,vGPU只支持数据中心级的Tesla GPU和部分Quadro GPU,大致如下:

架构型号
MaxwellM6, M10, M60
PascalP4, P6, P40, P100, P100 12GB
VoltaV100
TuringT4, RTX 6000, RTX 6000 passive, RTX 8000, RTX 8000 passive
AmpereA2, A10, A16, A40, RTX A5000, RTX A5500, RTX A6000
AdaL4, L40, RTX 6000 Ada

不过有热心大神开发了解锁补丁,可以在9,10,20系显卡上解锁vGPU功能,具体链接及教程如下:

{% link https://github.com/mbilker/vgpu_unlock-rs %}

{% link https://gitlab.com/polloloco/vgpu-proxmox %}

支持的平台

根据官方文档,目前支持的平台如下:

  • Citrix XenServer
  • Linux with KVM(比如Proxmox VE)
  • Microsoft Azure Stack HCI
  • Microsoft Windows Server(即Hyper-V)
  • Nutanix AHV
  • VMware vSphere ESXi

vGPU类型

NVIDIA官方介绍如下:

  • vCS:NVIDIA 虚拟计算服务器,加速基于 KVM 的基础架构上的虚拟化 AI 计算工作负载。(如GRID P40-1C
  • vWS: NVIDIA RTX 虚拟工作站,适用于使用图形应用程序的创意和技术专业人士的虚拟工作站。(如GRID P40-1Q
  • vPC: NVIDIA 虚拟 PC,适用于使用办公效率应用程序和多媒体的知识工作者的虚拟桌面 (VDI)。(如GRID P40-1B
  • vApp: NVIDIA 虚拟应用程序,采用远程桌面会话主机 (RDSH) 解决方案的应用程序流。(如GRID P40-1A

准备vGPU驱动

{% note color:warning 注意 本文中使用的Proxmox VE版本为8.0.3,内核版本为6.2.16-4-pve %}

移除企业源

Proxmox VE默认使用企业源,如果没有订阅密钥是没有权限访问的

echo "deb https://mirrors.tuna.tsinghua.edu.cn/proxmox/debian bookworm pve-no-subscription" >> /etc/apt/sources.list.d/pve-no-subscription.list
rm /etc/apt/sources.list.d/pve-enterprise.list

更新系统

apt update
apt dist-upgrade
reboot

保证内核为最新版本

安装必要工具

apt install -y git build-essential dkms pve-headers mdevctl

其中dkms保证在每次更新内核后会自动编译适应的驱动模块

启用IOMMU

一般系统

编辑/etc/default/grub,找到GRUB_CMDLINE_LINUX_DEFAULT="quiet",在其后添加:

Intel
intel_iommu=on iommu=pt
AMD
amd_iommu=on iommu=pt

结果应该如下(Intel):

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

ZFS上的系统

编辑/etc/kernel/cmdline,找到root=ZFS=rpool/ROOT/pve-1 boot=zfs,在其后添加:

Intel
intel_iommu=on iommu=pt
AMD
amd_iommu=on iommu=pt

结果应该如下(Intel):

root=ZFS=rpool/ROOT/pve-1 boot=zfs intel_iommu=on iommu=pt

现在更新引导配置:

proxmox-boot-tool refresh

禁止nouveau驱动

nouveau是一个开源的NVIDIA显卡驱动,它与vGPU驱动冲突,必须禁用它

echo "blacklist nouveau" >> /etc/modprobe.d/blacklist-nouveau.conf
echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf

加载vfio模块

编辑/etc/modules,添加如下内容:

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

更新initramfs

update-initramfs -u -k all

重启

reboot

检查IOMMU是否启用

重启后输入:

dmesg | grep -e DMAR -e IOMMU

在我的C602双路服务器上,它输出以下内容:

{% folding open:false %}

root@pve-r720:~# dmesg | grep -e DMAR -e IOMMU
[    0.000000] Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA
[    0.012034] ACPI: DMAR 0x000000007D3346F4 000158 (v01 DELL   PE_SC3   00000001 DELL 00000001)
[    0.012084] ACPI: Reserving DMAR table memory at [mem 0x7d3346f4-0x7d33484b]
[    0.591102] DMAR: IOMMU enabled
[    1.347160] DMAR: Host address width 46
[    1.347161] DMAR: DRHD base: 0x000000d1100000 flags: 0x0
[    1.347168] DMAR: dmar0: reg_base_addr d1100000 ver 1:0 cap d2078c106f0466 ecap f020de
[    1.347170] DMAR: DRHD base: 0x000000dd900000 flags: 0x1
[    1.347175] DMAR: dmar1: reg_base_addr dd900000 ver 1:0 cap d2078c106f0466 ecap f020de
[    1.347177] DMAR: RMRR base: 0x0000007f458000 end: 0x0000007f46ffff
[    1.347178] DMAR: RMRR base: 0x0000007f450000 end: 0x0000007f450fff
[    1.347180] DMAR: RMRR base: 0x0000007f452000 end: 0x0000007f452fff
[    1.347181] DMAR: ATSR flags: 0x0
[    1.347183] DMAR-IR: IOAPIC id 2 under DRHD base  0xd1100000 IOMMU 0
[    1.347185] DMAR-IR: IOAPIC id 0 under DRHD base  0xdd900000 IOMMU 1
[    1.347186] DMAR-IR: IOAPIC id 1 under DRHD base  0xdd900000 IOMMU 1
[    1.347187] DMAR-IR: HPET id 0 under DRHD base 0xdd900000
[    1.347188] DMAR-IR: x2apic is disabled because BIOS sets x2apic opt out bit.
[    1.347189] DMAR-IR: Use 'intremap=no_x2apic_optout' to override the BIOS setting.
[    1.347933] DMAR-IR: Enabled IRQ remapping in xapic mode
[    2.304979] DMAR: No SATC found
[    2.304981] DMAR: dmar0: Using Queued invalidation
[    2.304990] DMAR: dmar1: Using Queued invalidation
[    2.310738] DMAR: Intel(R) Virtualization Technology for Directed I/O

{% endfolding %}

关键在于DMAR: IOMMU enabled一行,此行表明IOMMU已启用。

安装vGPU驱动

{% note color:warning 注意 本节使用535.54.06版驱动,GRID版本为16.0。 %}

Proxmox VE作为KVM平台,自然需要KVM版的vGPU驱动

目前仅有16.0版的vGPU驱动支持新的6.2内核,15.3、15.1等版本最高支持到PVE 7

很不幸,NVIDIA不会让你随便下载高贵的GRID驱动(fuck-you-nvidia.jpg),你需要在这里注册一个免费的vGPU许可来下载驱动。

{% note color:warning 注意 申请免费许可时,请勿使用@gmail.com、@qq.com等免费邮箱,否则可能会面临人工审核,我的建议是使用自己域名的邮箱。 %}

{% note color:green 提示 觉得注册太麻烦?你也可以去佛西大佬的博客下载 %}

下载完成后,解压zip文件,在Host_Drivers文件夹中找到NVIDIA-Linux-x86_64-535.54.06-vgpu-kvm.run,将其上传到Proxmox VE中

在Proxmox VE中执行以下命令:

./NVIDIA-Linux-x86_64-535.54.06-vgpu-kvm.run --dkms

安装完成后,提示是否要注册DKMS模块,一定要选择Yes,这样在升级内核后,系统会重新编译适应新内核的驱动。

{% note color:warning 注意 由于Proxmox VE使用apt update升级系统时不会升级pve-headers,因此务必在升级系统前安装新的pve-headers,避免造成dkms编译失败。 %}

截屏2023-07-17 20.46.33

重启后执行nvidia-smi,在我的双Tesla P40机器上,输出以下内容(无视那些“vgpu”进程):

截屏2023-07-17 20.58.06

执行mdevctl types查看mdev类型:

{% folding open:false %}

root@pve-r720:~# mdevctl types
0000:04:00.0
  nvidia-156
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2B
    Description: num_heads=4, frl_config=45, framebuffer=2048M, max_resolution=5120x2880, max_instance=12
  nvidia-215
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2B4
    Description: num_heads=4, frl_config=45, framebuffer=2048M, max_resolution=5120x2880, max_instance=12
  nvidia-241
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1B4
    Description: num_heads=4, frl_config=45, framebuffer=1024M, max_resolution=5120x2880, max_instance=24
  nvidia-46
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1Q
    Description: num_heads=4, frl_config=60, framebuffer=1024M, max_resolution=5120x2880, max_instance=24
  nvidia-47
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2Q
    Description: num_heads=4, frl_config=60, framebuffer=2048M, max_resolution=7680x4320, max_instance=12
  nvidia-48
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-3Q
    Description: num_heads=4, frl_config=60, framebuffer=3072M, max_resolution=7680x4320, max_instance=8
  nvidia-49
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-4Q
    Description: num_heads=4, frl_config=60, framebuffer=4096M, max_resolution=7680x4320, max_instance=6
  nvidia-50
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-6Q
    Description: num_heads=4, frl_config=60, framebuffer=6144M, max_resolution=7680x4320, max_instance=4
  nvidia-51
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-8Q
    Description: num_heads=4, frl_config=60, framebuffer=8192M, max_resolution=7680x4320, max_instance=3
  nvidia-52
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-12Q
    Description: num_heads=4, frl_config=60, framebuffer=12288M, max_resolution=7680x4320, max_instance=2
  nvidia-53
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-24Q
    Description: num_heads=4, frl_config=60, framebuffer=24576M, max_resolution=7680x4320, max_instance=1
  nvidia-54
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1A
    Description: num_heads=1, frl_config=60, framebuffer=1024M, max_resolution=1280x1024, max_instance=24
  nvidia-55
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2A
    Description: num_heads=1, frl_config=60, framebuffer=2048M, max_resolution=1280x1024, max_instance=12
  nvidia-56
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-3A
    Description: num_heads=1, frl_config=60, framebuffer=3072M, max_resolution=1280x1024, max_instance=8
  nvidia-57
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-4A
    Description: num_heads=1, frl_config=60, framebuffer=4096M, max_resolution=1280x1024, max_instance=6
  nvidia-58
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-6A
    Description: num_heads=1, frl_config=60, framebuffer=6144M, max_resolution=1280x1024, max_instance=4
  nvidia-59
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-8A
    Description: num_heads=1, frl_config=60, framebuffer=8192M, max_resolution=1280x1024, max_instance=3
  nvidia-60
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-12A
    Description: num_heads=1, frl_config=60, framebuffer=12288M, max_resolution=1280x1024, max_instance=2
  nvidia-61
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-24A
    Description: num_heads=1, frl_config=60, framebuffer=24576M, max_resolution=1280x1024, max_instance=1
  nvidia-62
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1B
    Description: num_heads=4, frl_config=45, framebuffer=1024M, max_resolution=5120x2880, max_instance=24
0000:42:00.0
  nvidia-156
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2B
    Description: num_heads=4, frl_config=45, framebuffer=2048M, max_resolution=5120x2880, max_instance=12
  nvidia-215
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2B4
    Description: num_heads=4, frl_config=45, framebuffer=2048M, max_resolution=5120x2880, max_instance=12
  nvidia-241
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1B4
    Description: num_heads=4, frl_config=45, framebuffer=1024M, max_resolution=5120x2880, max_instance=24
  nvidia-46
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1Q
    Description: num_heads=4, frl_config=60, framebuffer=1024M, max_resolution=5120x2880, max_instance=24
  nvidia-47
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2Q
    Description: num_heads=4, frl_config=60, framebuffer=2048M, max_resolution=7680x4320, max_instance=12
  nvidia-48
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-3Q
    Description: num_heads=4, frl_config=60, framebuffer=3072M, max_resolution=7680x4320, max_instance=8
  nvidia-49
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-4Q
    Description: num_heads=4, frl_config=60, framebuffer=4096M, max_resolution=7680x4320, max_instance=6
  nvidia-50
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-6Q
    Description: num_heads=4, frl_config=60, framebuffer=6144M, max_resolution=7680x4320, max_instance=4
  nvidia-51
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-8Q
    Description: num_heads=4, frl_config=60, framebuffer=8192M, max_resolution=7680x4320, max_instance=3
  nvidia-52
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-12Q
    Description: num_heads=4, frl_config=60, framebuffer=12288M, max_resolution=7680x4320, max_instance=2
  nvidia-53
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-24Q
    Description: num_heads=4, frl_config=60, framebuffer=24576M, max_resolution=7680x4320, max_instance=1
  nvidia-54
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1A
    Description: num_heads=1, frl_config=60, framebuffer=1024M, max_resolution=1280x1024, max_instance=24
  nvidia-55
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2A
    Description: num_heads=1, frl_config=60, framebuffer=2048M, max_resolution=1280x1024, max_instance=12
  nvidia-56
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-3A
    Description: num_heads=1, frl_config=60, framebuffer=3072M, max_resolution=1280x1024, max_instance=8
  nvidia-57
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-4A
    Description: num_heads=1, frl_config=60, framebuffer=4096M, max_resolution=1280x1024, max_instance=6
  nvidia-58
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-6A
    Description: num_heads=1, frl_config=60, framebuffer=6144M, max_resolution=1280x1024, max_instance=4
  nvidia-59
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-8A
    Description: num_heads=1, frl_config=60, framebuffer=8192M, max_resolution=1280x1024, max_instance=3
  nvidia-60
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-12A
    Description: num_heads=1, frl_config=60, framebuffer=12288M, max_resolution=1280x1024, max_instance=2
  nvidia-61
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-24A
    Description: num_heads=1, frl_config=60, framebuffer=24576M, max_resolution=1280x1024, max_instance=1
  nvidia-62
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1B
    Description: num_heads=4, frl_config=45, framebuffer=1024M, max_resolution=5120x2880, max_instance=24

{% endfolding %}

配置vGPU授权服务器

众所周知,vGPU的授权费极其昂贵,不是富哥很难承受的起,很长一段时间内,众多玩家采用伪造PCI ID的形式来伪装成Quadro显卡,从而骗过NVIDIA的检测。但目前已经有成熟的开源vGPU许可服务器fastapi-dls可以直接使用了,官方还提供了Docker,这省了许多事。

安装容器

{% note color:green 提示 建议在虚拟机 / LXC中部署此Docker镜像,PVE中直接安装Docker可能会导致VM断网等问题 %}

# 拉取镜像
docker pull collinwebdesigns/fastapi-dls:latest
# 创建目录
mkdir -p /opt/fastapi-dls/cert
cd /opt/fastapi-dls/cert
# 生成公私钥
openssl genrsa -out /opt/fastapi-dls/cert/instance.private.pem 2048 
openssl rsa -in /opt/fastapi-dls/cert/instance.private.pem -outform PEM -pubout -out /opt/fastapi-dls/cert/instance.public.pem
# 生成SSL证书
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout  /opt/fastapi-dls/cert/webserver.key -out /opt/fastapi-dls/cert/webserver.crt
# 创建容器, 1825是授权天数, YOUR_IP处填VM / LXC的IP
docker volume create dls-db
docker run -d --restart=always -e LEASE_EXPIRE_DAYS=1825 -e DLS_URL=<YOUR_IP> -e DLS_PORT=443 -p 443:443 -v /opt/fastapi-dls/cert:/app/cert -v dls-db:/app/database collinwebdesigns/fastapi-dls:latest

自此,vGPU配置完成!

参考资料

NVIDIA Virtual GPU Software Documentation

佛西博客 - 在Proxmox VE 7.2 中开启vGPU_unlock,实现显卡虚拟化 (buduanwang.vip)

PolloLoco / NVIDIA vGPU Guide · GitLab

oscar.krause/fastapi-dls: Minimal Delegated License Service (DLS). This is a mirrored repo from https://git.collinwebdesigns.de/oscar.krause/fastapi-dls. - fastapi-dls - Gitea (publichub.eu)

collinwebdesigns/fastapi-dls - Docker Image | Docker Hub