Ubuntu20.04+VirtualGL+TigerVNCでリモートGUI環境を構築してみた
当サイトではアフィリエイト広告を利用しています
リモートPC(Ubuntu20.04)でGazeboなど、OpenGL経由でGPUを利用する環境へアクセスできる環境を構築したので、その過程を記録しておきます。
環境について
- OS: Linux (Ubuntu 20.04 LTS)
- CPU: AMD Ryzen
- MEM: 16GB
- GPU: Nvidia Geforce GTX 1660
- nvidia-dirver 470.xをインストール済
- すでにsshd設定済み
WindowManagerの準備
VNCでリモート接続を行う場合、起動スクリプトが煩雑なGNOME(gdm3)よりLXDEやXfce(lightdm)とするのが楽かと思われます。
利用環境にはGNOMEを入れていたので、削除してからLXDEを導入します。
まずは以下のようにGNOME系を一通り削除します。
$sudo apt purge adwaita-icon-theme gedit-common gir1.2-gdm-1.0 \
gir1.2-gnomebluetooth-1.0 gir1.2-gnomedesktop-3.0 gir1.2-goa-1.0 \
gnome-accessibility-themes gnome-bluetooth gnome-calculator gnome-calendar \
gnome-characters gnome-control-center gnome-control-center-data \
gnome-control-center-faces gnome-desktop3-data \
gnome-font-viewer \
gnome-initial-setup gnome-keyring gnome-keyring-pkcs11 gnome-logs \
gnome-mahjongg gnome-menus gnome-mines gnome-online-accounts \
gnome-power-manager gnome-screenshot gnome-session-bin gnome-session-canberra \
gnome-session-common gnome-settings-daemon gnome-settings-daemon-common \
gnome-shell gnome-shell-common gnome-shell-extension-appindicator \
gnome-shell-extension-desktop-icons gnome-shell-extension-ubuntu-dock \
gnome-startup-applications gnome-sudoku gnome-system-monitor gnome-terminal \
gnome-terminal-data gnome-themes-extra gnome-themes-extra-data gnome-todo \
gnome-todo-common gnome-user-docs gnome-user-docs-ru gnome-video-effects \
language-pack-gnome-en language-pack-gnome-en-base language-pack-gnome-ru \
language-pack-gnome-ru-base language-selector-gnome libgail18 libgail18 \
libgail-common libgail-common libgnome-autoar-0-0 libgnome-bluetooth13 \
libgnome-desktop-3-19 libgnome-games-support-1-3 libgnome-games-support-common \
libgnomekbd8 libgnomekbd-common libgnome-menu-3-0 libgnome-todo libgoa-1.0-0b \
libgoa-1.0-common libpam-gnome-keyring libsoup-gnome2.4-1 libsoup-gnome2.4-1 \
nautilus-extension-gnome-terminal pinentry-gnome3 yaru-theme-gnome-shell
$sudo apt purge gnome-getting-started-docs gnome-getting-started-docs-ru
$sudo apt remove gdm3
そしてlxdeをインストールします。
$sudo apt install lxde
LXDEのスリープ問題
また、LXDEの電源オプションの問題で、20分経過でスリープされてSSHやVNCが勝手に切れてしまう問題があります。 毎度毎度WoLで起動するのは面倒ですし、これはどうもGUI上からでは変更できないようだったので、systemctlから設定を変更します。
$sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
Created symlink /etc/systemd/system/sleep.target → /dev/null.
Created symlink /etc/systemd/system/suspend.target → /dev/null.
Created symlink /etc/systemd/system/hibernate.target → /dev/null.
Created symlink /etc/systemd/system/hybrid-sleep.target → /dev/null.
maskはDisableの強化版みたいです。
VirtualGLの導入
公式のドキュメントVirtualGL, Docにしたがって、インストール作業を勧めます。
インストール
一度WindowManagerを終了してインストールを行います。 今回は最新の3.0系をインストールしました。
# LXDE
$ systemctl status display-manager.service
● lightdm.service - Light Display Manager
Loaded: loaded (/lib/systemd/system/lightdm.service; indirect; vendor preset: en>
Active: active (running) since Wed 2022-05-11 15:01:53 JST; 34s ago
$ sudo cp /etc/X11/xorg.conf /etc/X11/xorg.conf.20220511_bak
$ sudo nvidia-xconfig
$ sudo apt install libegl1-mesa libglvnd-dev
$ wget -O virtualgl_3.0_amd64.deb https://sourceforge.net/projects/virtualgl/files/3.0/virtualgl_3.0_amd64.deb/download
$ sudo dpkg -i virtualgl_3.0_amd64.deb
$ sudo apt install -f
$sudo systemctl stop lightdm.service
$sudo rmmod nvidia_uvm
$sudo rmmod nvidia_drm
$sudo rmmod nvidia_modeset
rmmod: ERROR: Module nvidia_drm is in use
とエラーが出る場合は、
sudo lsof /dev/nvidia*
でプロセス特定してkillします。
そしてVirtualGLの初期設定を行います。
$ sudo vglserver_config
1) Configure server for use with VirtualGL (GLX + EGL back ends)
2) Unconfigure server for use with VirtualGL (GLX + EGL back ends)
3) Configure server for use with VirtualGL (EGL back end only)
4) Unconfigure server for use with VirtualGL (EGL back end only)
X) Exit
Choose:
1
WARNING: Configuring this server for use with VirtualGL will disable the
ability to log in locally with a Wayland session.
Continue?
[Y/n]
y
Restrict 3D X server access to vglusers group (recommended)?
[Y/n]
y
Restrict framebuffer device access to vglusers group (recommended)?
[Y/n]
y
Disable XTEST extension (recommended)?
[Y/n]
y
... Creating vglusers group ...
groupadd: グループ 'vglusers' は既に存在します
Could not add vglusers group (probably because it already exists.)
... Granting read permission to /etc/opt/VirtualGL/ for vglusers group ...
... Creating /etc/modprobe.d/virtualgl.conf to set requested permissions for
/dev/nvidia* ...
... Attempting to remove nvidia module from memory so device permissions
will be reloaded ...
... Granting write permission to /dev/nvidia-modeset /dev/nvidia-uvm /dev/nvidia-uvm-tools /dev/nvidia0 /dev/nvidiactl for vglusers group ...
... Modifying /etc/X11/xorg.conf to enable DRI permissions
for vglusers group ...
... Adding vglgenkey to /etc/gdm3/Init/Default script ...
... Creating /usr/share/gdm/greeter/autostart/virtualgl.desktop ...
... Disabling Wayland in /etc/gdm3/custom.conf ...
Done. You must restart the display manager for the changes to take effect.
また、ここでsshd_configでX11Forwardingを許可、UseLoginを無効にしておきます。 UseLoginはデフォルトでOffらしいので、古い環境以外は関係ないと思いますが(OpenSSH7.4で廃止されたとか?)。
VNCの導入
続いてVNCの導入を行います。今回はTigerVNCを選択します。 VirtulaGLと同開発元のTurboVNCでなくてもVirtualGLには対応しているVNCServerは多い用で、ここではリポジトリに存在して管理しやすいTigerVNCを利用します。
VNC接続時はクライアントではAuto Scaleとしておくと使いやすいです。
$ sudo systemctl start lightdm.service
$ sudo apt install tigervnc-standalone-server
$ sudo usermod -a -G vglusers username
$ vncserver
# setting password
$ vncserver -kill :1
$ echo "vglrun startlxde" > ~/.vnc/xstartup
$ chmod 755 ~/.vnc/xstartup
$ vnvserver
VNCの簡単な使い方は以下の通りです。 PCの再起動をしてもvncserverの起動状況は残りますので、手動で終了する必要があります。
# パスワード設定
$vncpasswd
# 起動
$vncserver
$vncserver :1 # Port5901での起動(デフォルト)
# リスト
$vncserver -list
# 終了
$vncserver -kill :1
これでクライアント側からVNC接続ができるようになりました。
安全のためにssh転送経由で外部から接続するようにしています。
LD_PRELOAD設定(VirtualGL 3.0)
今回は最新の3.0を利用したこともあり、比較的情報のある2.x系と一部設定が違うようです。LD_PRELOADまわりなど。
su
などの実行時に以下のようなエラーが出ました。
$ su -
ERROR: ld.so: object 'libdlfaker.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libvglfaker.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
virtualgl3.0ではprofileにLD_PRELOAD設定をするのではなくて公式Docにあるようにsetuidすれば良いようです。 これでsuなどを行った際にERRORが表示されることはなくなりました。
chmod u+s /usr/lib/libvglfaker.so
chmod u+s /usr/lib/libdlfaker.so
なお、firefoxでabout:supportでWEBGL2.0はNVIDIAにはなってないが、WebGLデモページとかは問題なく動いているようにも見えます。 このあたりも2.x系とは異なるのでしょうか。
LD_PRELOADの設定(VirtualGL 2.x系?)
su
実行時のLD_PRELOADエラーに関しては~/.profile
に以下を追加するとよいという情報もありますが、VirtualGL3.0では機能しないようです。
export LD_PRELOAD=/usr/lib/libdlfaker.so:/usr/lib/libvglfaker.so:$LD_PRELOAD
設定後、VNC上でターミナル開くと以下のようになってしまいます。
ERROR: ld.so: object '/usr/lib//usr/lib/' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib//usr/lib/' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib//usr/lib/' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib//usr/lib/' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib//usr/lib/' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
~$ echo $LD_PRELOAD
libdlfaker.so:libvglfaker.so:/usr/lib//usr/lib/
2.x系で通用した対処方法のようです。3.0ではchmod u+s
の方がドキュメントに記載されています。
Glmark2によるテスト
また、glmark2でテストしようとしても、NVIDIA Driverの問題か途中で終了します。 glmark2 Issue, Ubuntu Issueなどに問題として報告されているようです。
$ glmark2
=======================================================
glmark2 2021.02
=======================================================
OpenGL Information
GL_VENDOR: NVIDIA Corporation
GL_RENDERER: NVIDIA GeForce GTX 1660/PCIe/SSE2
GL_VERSION: 4.6.0 NVIDIA 470.103.01
=======================================================
[build] use-vbo=false: FPS: 2190 FrameTime: 0.457 ms
[build] use-vbo=true: FPS: 2564 FrameTime: 0.390 ms
[texture] texture-filter=nearest: FPS: 2534 FrameTime: 0.395 ms
[texture] texture-filter=linear: FPS: 2534 FrameTime: 0.395 ms
[texture] texture-filter=mipmap: FPS: 2534 FrameTime: 0.395 ms
[shading] shading=gouraud: FPS: 2555 FrameTime: 0.391 ms
[shading] shading=blinn-phong-inf: FPS: 2564 FrameTime: 0.390 ms
[shading] shading=phong: FPS: 2575 FrameTime: 0.388 ms
[shading] shading=cel: FPS: 2506 FrameTime: 0.399 ms
[bump] bump-render=high-poly: FPS: 2553 FrameTime: 0.392 ms
[bump] bump-render=normals: FPS: 2552 FrameTime: 0.392 ms
Error: Failed to add fragment shader from file None:
Error: 0(15) : error C0000: syntax error, unexpected identifier, expecting "::" at token "highp"
Error: 0(36) : warning C1503: undefined variable "TextureCoord"
Error: 0(37) : warning C1503: undefined variable "TextureCoord"
Error: 0(38) : warning C1503: undefined variable "TextureCoord"
Error:
[bump] bump-render=height: Set up failed
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 2676 FrameTime: 0.374 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 2530 FrameTime: 0.395 ms
[pulsar] light=false:quads=5:texture=false: FPS: 2520 FrameTime: 0.397 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 1176 FrameTime: 0.850 ms
[desktop] effect=shadow:windows=4: FPS: 930 FrameTime: 1.075 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 1087 FrameTime: 0.920 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 1110 FrameTime: 0.901 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 1248 FrameTime: 0.801 ms
[ideas] speed=duration: FPS: 2161 FrameTime: 0.463 ms
[jellyfish] <default>: FPS: 2475 FrameTime: 0.404 ms
Error: Failed to add fragment shader from file None:
Error: 0(26) : warning C7022: unrecognized profile specifier "highp"
Error: 0(26) : error C0502: syntax error at token "highp"
Error:
Error: Failed to add fragment shader from file None:
Error: 0(75) : warning C7022: unrecognized profile specifier "highp"
Error: 0(75) : error C0502: syntax error at token "highp"
Error:
[terrain] <default>:Segmentation fault (??????????)
一方、glxgearsなどは正常にFPS発揮できているのでVirtualGLは問題なく機能しているようにも思えます。
$ glxgears
25260 frames in 5.0 seconds = 5051.934 FPS
これで一通りのVirtualGL+VNC環境が完成しました。
まとめ
- VirtualGL + TigerVNCでリモート環境を構築
- glxgearsで正常にFPSが発揮できることを確認
- GUI対応のGPUリモート環境の構築が出来た