コンテナでGPU acceralatedなWebGLを動かしてブラウザゲームを遊ぶ

モチベーション

とあるブラウザゲームをプレイしています。 このゲームは、1日の回数制限があるが報酬がおいしいコンテンツ、いわゆる日課がたくさんあります。 毎日やるのは正直面倒です。

なので、基本的に「フルオート」機能で消化します。 これはスキル発動や攻撃行動を自動で行う機能で、オンにすれば自動で敵を倒してくれるので便利です。 ただし、操作を自動化するだけで戦闘自体はリアルタイムで進行するため、画面はアクティブにしておく必要があります。 スマホで「フルオートだけオンにして放置する、別の作業をする」といったことは出来ないので、少々面倒です。

そこで、簡単にフルオート放置ができる環境を作ってみます。

  • PC/スマホから操作できること
  • ブラウザだけで操作できること
  • 利用規約に則ること

実現方法

  1. DockerとNVIDIA Container ToolkitでX11OpenGL(WebGL)が動くコンテナを作る
  2. GoogleChromeを動作させる
  3. noVNCでブラウザから操作可能にする

少し調べてみると「ホスト側のtmp/.X11-unix$DISPLAYをコンテナへ共有し、描画はホスト側で行う」という手法が多く散見されます。 ホストを汚したくない&ヘッドレスにしたいので、コンテナ側に全て閉じ込める方式にします。 具体的には、X.Org Serverもコンテナ内で実行します。

諸元

とても古い機材ですが、とりあえずNVIDIA Container Toolkitに対応してさえいればなんでもいいはずです。

CPU Core i5-3230M
Host OS Ubuntu 20.04
Container base Ubuntu 20.04
Docker version 20.10.8
GPU NVIDIA GeForce 650M
GPU driver version 470.57.02
CUDA version 11.4

構築

ホスト

NVIDIA関連のドライバやミドルウェアをインストールします。 以前は依存関係が複雑で面倒だったような気がしますが、現在は非常に簡単になったようです。

ドライバ

リポジトリを追加してcuda-driversをインストールすれば最新版が入ります。 ここの通りやるだけです。

ミドルウェア

こちらもリポジトリを追加してnvidia-docker2だけインストールすれば、container-toolkitなども同時にインストールされます。 ここの通りやるだけです。

nvidia-smiコマンドが実行できればOK。 次の作業のために、実際にインストールされたドライバのバージョンを確認しておきます。

$ nvidia-smi
Sun Aug 15 06:02:11 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.57.02    Driver Version: 470.57.02    CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0 N/A |                  N/A |
| N/A   56C    P8    N/A /  N/A |     79MiB /  2000MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

コンテナ

NVIDIAがコンテナをいくつか公開していますが、これらにはX11に必要なファイルを含んでいないようです。 そもそも現状ではX11をサポートしていません。

Display (e.g. X11, Wayland) is not officially supported.

なので自分で環境構築する必要があります。コードはこちら。

ホストとコンテナのドライバのバージョンを合わせる必要があるので、ビルド時の引数で指定します。

docker-compose build --build-arg DRIVER_VERSION=$(nvidia-smi --query-gpu=driver_version --format=csv,noheader)
docker-compose up -d

:8081/vnc.htmlにアクセスすればnoVNCの画面が出ます。 自動的にOpenboxとターミナルが起動するようにしてあります。

f:id:nullsnet:20210815184433p:plain

ここからChromeを起動する場合、rootなのでgoogle-chrome --no-sandboxとする必要があります。

できたもの

コンテナ上で動作するGPU acceralatedなWebGLの環境ができました。 ブラウザを閉じても問題なくフルオートできています。 速度も問題なさそうです。 HTML5に対応してさえいれば、どんな端末からでも操作可能です。 これでフルオート放置が捗ります。

ちゃんとした(?)用途としては

とかがあるでしょうか。あんまりなさそうですが。

ドライバアップデート時

ホストOSのドライバをアップデートをしたらコンテナがうまく起動しなくなった。 Xorgの起動に失敗しているようだ。

/usr/bin/Xorg :0

X.Org X Server 1.20.13
X Protocol Version 11, Revision 0
Build Operating System: linux Ubuntu
Current Operating System: Linux 7b222ef168e6 5.4.0-104-generic #118-Ubuntu SMP Wed Mar 2 19:02:41 UTC 2022 x86_64
Kernel command line: BOOT_IMAGE=/vmlinuz-5.4.0-104-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro maybe-ubiquity
Build Date: 14 December 2021  02:14:13PM
xorg-server 2:1.20.13-1ubuntu1~20.04.2 (For technical support please see http://www.ubuntu.com/support) 
Current version of pixman: 0.38.4
        Before reporting problems, check http://wiki.x.org
        to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
        (++) from command line, (!!) notice, (II) informational,
        (WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/var/log/Xorg.0.log", Time: Sun Mar 13 17:09:39 2022
(==) Using config file: "/etc/X11/xorg.conf"
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
(EE) 
Fatal server error:
(EE) Cannot run in framebuffer mode. Please specify busIDs        for all framebuffer devices
(EE) 
(EE) 
Please consult the The X.Org Foundation support 
         at http://wiki.x.org
 for help. 
(EE) Please also check the log file at "/var/log/Xorg.0.log" for additional information.
(EE) 
(EE) Server terminated with error (1). Closing log file.

dmesgを見るとこんなログが出ている。

NVRM: API mismatch: the client has the version 470.57.02, but
NVRM: this kernel module has the version 470.103.01.  Please
NVRM: make sure that this kernel module

ホスト側とコンテナ側でドライバのバージョンがずれてるだけなので、コンテナをビルドしなおせばOK。