配置好能夠使用 GPU 的容器之後,突然想到是否可以使用高效能 GPU 來進行 Steam Link 呢。
使用遠端 GPU 來啟用 Xorg Server
X11 Forward
Xorg 是 C/S 架構的,原生支援透過網路來進行轉發。然而,X11 Forward 實際上是使用本地硬體資源進行渲染的。當在自己的電腦上執行 X11 轉發的 Steam ,另一臺電腦上登陸的 Steam 則會立即顯示「遠端暢玩可用」。這時候使用的仍然是本地資源,並不是我們期望的。因此,要想讓使用遠端 GPU 進行渲染,那麼就必須在遠端啟用 Xserver。
Remote Xserver
首先需要配置合適的 xorg.conf
。和通常的配置檔案並無太多不同。
- 裝置模組。
1 2 3 4 5 6
Section "Device" Identifier "Card0" Driver "nvidia" BusID "PCI:175:0:0" Option "AllowEmptyInitialConfiguration" EndSection
- 螢幕模組。自定義螢幕的 DPI ,否則就會使用預設的超小 DPI。
1 2 3 4 5 6 7 8 9 10 11 12 13
Section "Screen" Identifier "Screen0" Device "Card0" Monitor "Monitor0" DefaultDepth 24 Option "AllowEmptyInitialConfiguration" Option "HardDPMS" "false" SubSection "Display" Depth 24 Virtual 2560 1440 Option "DPI" "144x144" EndSubSection EndSection
然而發現在非特權模式下,容器內部始終無法啟動 Xserver,似乎必須拿到 /dev/tty0 的讀寫許可權才行。於是為了保持非特權模式的容器,最終選擇在宿主機啟動 Xerver,然後將其轉發到內部網路中,再將容器內部的 DISPLAY 變數設定為外部宿主機啟動的 Xserver 處。
可以使用 socat
將 unix socket 轉為 TCP(或者直接在 LXC 配置中掛載進容器):
|
|
啟動 Xserver 之後,可以看到 nvidia-smi
已經有了 Xorg 這個程式在跑了。
之後,就可以使用外部的 GPU 來渲染容器上跑的 GUI 程式了。簡單的測試如 xclock
。
Indirect GLX 以及跑 32 位 的 Steam
然而,如果跑 GLX 程式,如 glxgears
時,則會報錯。需要做的改動有兩點:
- 在
xorg.conf
File 模組處新增 Nvidia 的 Xorg modules 的路徑:1 2 3 4
Section "ServerFlags" Option "AllowIndirectGLX" "on" Option "IndirectGLX" "on" EndSection
- 在
xorg.conf
ServerFlags 處啟用 Indirect GLX:1 2 3 4
Section "Files" ModulePath "/usr/lib/xorg/modules" ModulePath "/usr/lib/x86_64-linux-gnu/nvidia/xorg" EndSection
這下就可以執行 glxgears
,glxinfo
等程式了。那麼是不是 Steam 也可以跑了呢?答案是否定的。Steam 一直以來都是 32 位的,而最新版的驅動都沒有再支援 32 位的 GLX。Debian stable 上當時的 libglx-nvidia0:i386
包的版本是 418.152,與實際安裝的驅動版本 455.23.05 差了很多。正當想放棄時,突然想顯示卡其實已經被驅動起來了,那麼在容器內部也就沒有必要執著於使用最新的驅動(無非只是一堆檔案而已)。這樣看來,容器化甚至成了一個好處,可以使得容器內選擇性使用相容的低版本庫函式。
於是將容器內部的 libglx-nvidia0
包及其依賴統一替換為了有 i386 版本的低版本。終於可以將 32 位版本的 GLX 程式跑起來啦。
Ready for Steam Link?
最後需要做的一步是組網。Steam Link 要求兩臺裝置必須在一個區域網之內。熟悉起見使用了 Wireguard 。 然而最後雖然已經確定在一個網段內了,還是無法正常使用 Steam Link ,原因出在無法連線一個公網埠上面,感覺有可能是需要兩臺裝置有同樣的公網出口來和 Steam 建立連線。
最終是還是失敗了 😢 。
(本文純屬技術實驗性質)