├── .gitignore ├── screenshot.png ├── utils ├── install-nvidia-driver.sh ├── set-nvidia-gpus-performance.sh └── install-docker.sh ├── server.sh ├── AWS.md ├── run.sh ├── Dockerfile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | source_me.sh 2 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryought/glx-docker-headless-gpu/HEAD/screenshot.png -------------------------------------------------------------------------------- /utils/install-nvidia-driver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | wget https://us.download.nvidia.com/tesla/418.87/NVIDIA-Linux-x86_64-418.87.01.run 3 | sudo bash NVIDIA-Linux-x86_64-418.87.01.run 4 | -------------------------------------------------------------------------------- /utils/set-nvidia-gpus-performance.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # for Nvidia Tesla T4 on AWS G4 instances 3 | # https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/optimize_gpu.html 4 | sudo nvidia-persistenced 5 | sudo nvidia-smi --auto-boost-default=0 6 | sudo nvidia-smi -ac 5001,1590 7 | -------------------------------------------------------------------------------- /server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -t sim . && \ 3 | # docker run --device=/dev/tty0:rw -it --rm --gpus all \ 4 | docker run --privileged -it --rm --gpus all \ 5 | -p 8081:8081 \ 6 | -e RESOLUTION=1280x720 \ 7 | -e VNCPASS=pass \ 8 | --name sim sim 9 | # -v $HOME/hoge:/hoge:ro \ 10 | -------------------------------------------------------------------------------- /AWS.md: -------------------------------------------------------------------------------- 1 | # AWSでやる場合の手順書 2 | 3 | ## インスタンス起動 4 | g4dn.2xlargeの立ち上げ 5 | ベースAMIは素のubuntu18.04 6 | 7 | ## インスタンス内準備 8 | 9 | - ドライバインストール 10 | https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/install-nvidia-driver.html 11 | https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/optimize_gpu.html 12 | など参照 13 | - dockerのインストール 14 | utils/install-docker.sh参照 15 | 16 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | # inside docker script 2 | trap 'kill $(jobs -p)' EXIT 3 | 4 | # 0. generate xorg.conf 5 | BUS_ID=$(nvidia-xconfig --query-gpu-info | grep 'PCI BusID' | sed -r 's/\s*PCI BusID : PCI:(.*)/\1/') 6 | nvidia-xconfig -a --virtual=$RESOLUTION --allow-empty-initial-configuration --enable-all-gpus --busid $BUS_ID 7 | 8 | # 1. launch X server 9 | Xorg :0 & 10 | sleep 1 # wait for the server gets ready 11 | 12 | # 2. start x11 and vnc connection 13 | # to inspect logs in detail, use --verbose 14 | x11vnc -display :0 -passwd $VNCPASS -forever -rfbport 5900 & 15 | sleep 2 # wait for the server gets ready 16 | 17 | # 2.5 start audio 18 | # this is not required. 19 | # pulseaudio --start 20 | # sleep 2 21 | 22 | # 3. start noVNC 23 | /noVNC-1.1.0/utils/launch.sh --vnc localhost:5900 --listen 8081 & 24 | sleep 2 25 | 26 | echo 'running noVNC at http://localhost:8081/vnc.html?host=localhost&port=8081' 27 | 28 | # 3. start simulator 29 | export DISPLAY=:0 30 | openbox 31 | -------------------------------------------------------------------------------- /utils/install-docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # install docker-ce and nvidia-container-runtime on Debian/Ubuntu 3 | # this requires sudo 4 | 5 | # https://nvidia.github.io/nvidia-container-runtime/ 6 | curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \ 7 | sudo apt-key add - 8 | distribution=$(. /etc/os-release;echo $ID$VERSION_ID) 9 | curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \ 10 | sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list 11 | sudo apt-get update 12 | sudo apt-get install nvidia-container-runtime 13 | 14 | # https://docs.docker.com/v17.09/engine/installation/linux/docker-ce/ubuntu/#upgrade-docker-ce 15 | curl -fsSL get.docker.com -o get-docker.sh 16 | sudo sh get-docker.sh 17 | 18 | # add $USER to docker group 19 | # to run without docker 20 | sudo gpasswd -a $USER docker 21 | 22 | # to test (with gpu) 23 | # docker run --gpus all nvidia/cuda nvidia-smi 24 | # or (without gpu) 25 | # docker run hello-world 26 | 27 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | # Make all NVIDIA GPUS visible, but I want to manually install drivers 4 | ARG NVIDIA_VISIBLE_DEVICES=all 5 | # Supress interactive menu while installing keyboard-configuration 6 | ARG DEBIAN_FRONTEND=noninteractive 7 | 8 | # Error constructing proxy for org.gnome.Terminal:/org/gnome/Terminal/Factory0: Failed to execute child process dbus-launch (No such file or directory) 9 | # fix by setting LANG https://askubuntu.com/questions/608330/problem-with-gnome-terminal-on-gnome-3-12-2 10 | # to install locales https://stackoverflow.com/questions/39760663/docker-ubuntu-bin-sh-1-locale-gen-not-found 11 | RUN apt-get clean && \ 12 | apt-get update && \ 13 | apt-get install -y locales && \ 14 | rm -rf /var/lib/apt/lists/* && \ 15 | locale-gen en_US.UTF-8 16 | ENV LANG en_US.UTF-8 17 | ENV LANGUAGE en_US:en 18 | ENV LC_ALL en_US.UTF-8 19 | 20 | # (1) Install Xorg and NVIDIA driver inside the container 21 | # Almost same procesure as nvidia/driver https://gitlab.com/nvidia/driver/blob/master/ubuntu16.04/Dockerfile 22 | 23 | # (1-1) Install prerequisites 24 | RUN dpkg --add-architecture i386 && \ 25 | apt-get update && apt-get install -y --no-install-recommends \ 26 | apt-utils \ 27 | build-essential \ 28 | ca-certificates \ 29 | curl \ 30 | wget \ 31 | vim \ 32 | zip \ 33 | unzip \ 34 | git \ 35 | python \ 36 | kmod \ 37 | libc6:i386 \ 38 | pkg-config \ 39 | libelf-dev && \ 40 | rm -rf /var/lib/apt/lists/* 41 | 42 | # (1-2) Install xorg server and xinit BEFORE INSTALLING NVIDIA DRIVER. 43 | # After this installation, command Xorg and xinit can be used in the container 44 | # if you need full ubuntu desktop environment, the line below should be added. 45 | # ubuntu-desktop \ 46 | RUN apt-get update && apt-get install -y \ 47 | xinit && \ 48 | rm -rf /var/lib/apt/lists/* 49 | 50 | # (1-3) Install NVIDIA drivers, including X graphic drivers 51 | # Same command as nvidia/driver, except --x-{prefix,module-path,library-path,sysconfig-path} are omitted in order to make use default path and enable X drivers. 52 | # Driver version must be equal to host's driver 53 | # Install the userspace components and copy the kernel module sources. 54 | ENV DRIVER_VERSION=410.129-diagnostic 55 | ENV DRIVER_VERSION_PATH=410.129 56 | RUN cd /tmp && \ 57 | curl -fSsl -O https://us.download.nvidia.com/tesla/$DRIVER_VERSION_PATH/NVIDIA-Linux-x86_64-$DRIVER_VERSION.run && \ 58 | sh NVIDIA-Linux-x86_64-$DRIVER_VERSION.run -x && \ 59 | cd NVIDIA-Linux-x86_64-$DRIVER_VERSION && \ 60 | ./nvidia-installer --silent \ 61 | --no-kernel-module \ 62 | --install-compat32-libs \ 63 | --no-nouveau-check \ 64 | --no-nvidia-modprobe \ 65 | --no-rpms \ 66 | --no-backup \ 67 | --no-check-for-alternate-installs \ 68 | --no-libglx-indirect \ 69 | --no-glvnd-egl-client \ 70 | --no-glvnd-glx-client \ 71 | --no-install-libglvnd && \ 72 | mkdir -p /usr/src/nvidia-$DRIVER_VERSION && \ 73 | mv LICENSE mkprecompiled kernel /usr/src/nvidia-$DRIVER_VERSION && \ 74 | sed '9,${/^\(kernel\|LICENSE\)/!d}' .manifest > /usr/src/nvidia-$DRIVER_VERSION/.manifest 75 | # this option cannot be used on newer driver 76 | # --no-glvnd-egl-client \ 77 | # --no-glvnd-glx-client \ 78 | 79 | # (2) Configurate Xorg 80 | # (2-1) Install some necessary softwares 81 | # 82 | # pkg-config: nvidia-xconfig requires this package 83 | # mesa-utils: This package includes glxgears and glxinfo, which is useful for testing GLX drivers 84 | # x11vnc: Make connection between x11 server and VNC client. 85 | # x11-apps: xeyes can be used to make sure that X11 server is running. 86 | # 87 | # Note: x11vnc in ubuntu18.04 is useless beacuse of stack smashing bug. See below to manual compilation. 88 | RUN apt-get update && apt-get install -y --no-install-recommends \ 89 | mesa-utils \ 90 | x11-apps && \ 91 | rm -rf /var/lib/apt/lists/* 92 | 93 | # solution for the `stack smashing detected` issue 94 | # https://github.com/LibVNC/x11vnc/issues/61 95 | RUN apt-get update && apt-get install -y --no-install-recommends \ 96 | automake autoconf libssl-dev xorg-dev libvncserver-dev && \ 97 | rm -rf /var/lib/apt/lists/* && \ 98 | git clone https://github.com/LibVNC/x11vnc.git && \ 99 | cd x11vnc && \ 100 | ./autogen.sh && \ 101 | make && \ 102 | cp src/x11vnc /usr/bin/x11vnc 103 | 104 | # (2-2) Optional vulkan support 105 | # vulkan-utils includes vulkan-smoketest, benchmark software of vulkan API 106 | RUN apt-get update && apt-get install -y --no-install-recommends \ 107 | libvulkan1 vulkan-utils && \ 108 | rm -rf /var/lib/apt/lists/* 109 | 110 | # for test 111 | RUN apt-get update && apt-get install -y --no-install-recommends \ 112 | firefox openbox && \ 113 | rm -rf /var/lib/apt/lists/* 114 | 115 | # sound driver and GTK library 116 | # If you want to use sounds on docker, try `pulseaudio --start` 117 | RUN apt-get update && apt-get install -y --no-install-recommends \ 118 | alsa pulseaudio libgtk2.0-0 && \ 119 | rm -rf /var/lib/apt/lists/* 120 | 121 | # novnc 122 | # download websockify as well 123 | RUN wget https://github.com/novnc/noVNC/archive/v1.1.0.zip && \ 124 | unzip -q v1.1.0.zip && \ 125 | rm -rf v1.1.0.zip && \ 126 | git clone https://github.com/novnc/websockify /noVNC-1.1.0/utils/websockify 127 | 128 | # Xorg segfault error 129 | # dbus-core: error connecting to system bus: org.freedesktop.DBus.Error.FileNotFound (Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory) 130 | # related? https://github.com/Microsoft/WSL/issues/2016 131 | RUN apt-get update && apt-get install -y --no-install-recommends \ 132 | dbus-x11 \ 133 | libdbus-c++-1-0v5 && \ 134 | rm -rf /var/lib/apt/lists/* 135 | 136 | # (3) Run Xorg server + x11vnc + X applications 137 | # see run.sh for details 138 | COPY run.sh /run.sh 139 | CMD ["bash", "/run.sh"] 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Run Unity apps in docker container on headless Nvidia GPU server 2 | 3 | OpenGLやGLXなどを使ってグラフィック用途でGPUを使うアプリケーションを、画面のないheadlessサーバー上で、しかもDocker内で動かす方法のまとめ。 4 | 5 | 具体的には、Unityで作られたソフト本体の自動テスト環境やそれを使ったCI環境を、GPUインスタンスを含んだkubernetesクラスタ上に構築したい時に使える。 6 | 7 | 8 | ## Update: support AWS and noVNC 9 | 10 | - AWSのg4インスタンスでの動作を確認しました。 11 | - noVNCを使用しブラウザからアクセスできるようにしました。 12 | 13 | 実行するには: 14 | ``` 15 | bash server.sh 16 | ``` 17 | 18 | 19 | ## Background 20 | 21 | 自動テストサーバーを作るために、 https://github.com/lgsvl/simulator をKubernetes上で動かしたかった。 22 | 23 | ECSもGPUインスタンスをサポートし始めたので、Docker内でグラフィック系アプリケーションをGPU機能込みで閉じ込めたい需要は割とあると思うので、まとめておく。 24 | 25 | ## Method 26 | とりあえず使いたい人向けに手順をまず書く。 27 | 28 | ### 1. Google Cloud Platform Compute Engineのインスタンスのセットアップ 29 | GPUインスタンス上で、GPUのドライバとnvidia-docker2をインストールする。 30 | 31 | まず使うVMをGCP Compute Engineで立ち上げる。基本的にはNVIDIA GPUが搭載されているインスタンスを立ち上げて、GPUドライバ+nvidia-docker2をインストールすれば良いが、Marketplaceから入手できるDeep Learning VMをdeployするとインストール済みイメージが載った状態のVMにアクセスできる。 32 | 33 | ここで使ったのは 34 | 35 | - Deep Learning VM by Google 36 | - n1-highmem-2 37 | - 1 x NVIDIA Tesla T4 38 | - 100GB HDD 39 | - Tensorflow 1.14 frameworkを有効化(これはどれでも良さそう) 40 | - nvidiaドライバ込み 41 | 42 | それ以外は標準のままのインスタンス。us-west1-bに立ち上げた。起動時にwarningが出るが気にしない。ブラウザ上で設定したが、同様のコマンドは以下。 43 | 44 | ``` 45 | gcloud compute --project=$PROJECT_NAME create $INSTANCE_NAME \ 46 | --zone=us-west1-b \ 47 | --machine-type=n1-highmem-2 \ 48 | --subnet=default \ 49 | --network-tier=PREMIUM \ 50 | --metadata=framework=TensorFlow:1.13,google-logging-enable=0,google-monitoring-enable=0,install-nvidia-driver=True,status-config-url=https://runtimeconfig.googleapis.com/v1beta1/projects/sever-rendering/configs/tensorflow-1-config,status-uptime-deadline=600,status-variable-path=status,title=TensorFlow/Keras/Horovod.CUDA10.0,version=27 \ 51 | --maintenance-policy=TERMINATE \ 52 | --service-account=471732791036-compute@developer.gserviceaccount.com \ 53 | --scopes=https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/cloud.useraccounts.readonly,https://www.googleapis.com/auth/cloudruntimeconfig \ 54 | --accelerator=type=nvidia-tesla-t4,count=1 \ 55 | --tags=deeplearning-vm \ 56 | --image=tf-1-14-cu100-20190619 \ 57 | --image-project=click-to-deploy-images \ 58 | --boot-disk-size=100GB \ 59 | --boot-disk-type=pd-standard \ 60 | --boot-disk-device-name=tensorflow-1-vm-1 \ 61 | --labels=goog-dm=tensorflow-1 62 | ``` 63 | 64 | ssh port forwardを使うので、sshクライアントからログインできるようにセットアップしておく。(コンソールからssh鍵を登録する。`ssh-keygen -t rsa -C "$USERNAME" -b 4096 -f ~/.ssh/$KEYNAME` コメントのユーザー名に指定したユーザーでしかログインできないので注意。) 65 | 66 | sshログインして`nvidia-smi`を実行して、GPUが検出されることと、入っているドライババージョンを確認 67 | 上のVMでは、Tesla T4とドライババージョン410.104が入っていた。 68 | 69 | 70 | ### 2. container立ち上げ 71 | X11サーバーとアプリケーションの入ったdocker containerをビルド、立ち上げる。 72 | 73 | ``` 74 | nvidia-docker build -t x11-GL-docker . 75 | docker run --runtime=nvidia --privileged -it --rm \ 76 | -p 5900:5900 \ # or --net=host 77 | -e BUSID=PCI:0:4:0 \ 78 | -e SCREEN_RESOLUTION=1280x1024 \ 79 | -e VNC_PASSWORD=passpass \ 80 | -v /home/ryonakabayashi/x11-docker/lgsvlsimulator-linux64-2019.05:/lg \ 81 | --name x11-GL-docker x11-GL-docker 82 | ``` 83 | 84 | run.shがdocker内で実行される。 85 | 86 | 5900ポートはVNC用。またホストマシンに一度ログインして、`nvidia-xconfig --query-gpu-info`を実行し、BUSIDを控えておく。 87 | 88 | ### 3. port forwarding, VNC connection 89 | docker内で起動しているVNCサーバーに、ssh経由で接続する。 90 | 91 | ``` 92 | ssh -i "$KEYFILE" -L 5900:localhost:5900 $USERNAME@$GCP_PUBLIC_IP -N & 93 | ``` 94 | 95 | でトンネルを作り、VNCクライアント(macならFinder)で`vnc://localhost:5900`に接続する。 96 | 97 | ![img](screenshot.png) 98 | 99 | リモートのdocker内でレンダリングした結果が手元のmacbookで確認できる環境がこれで整った。 100 | 101 | ## 何をしているか 102 | 2つの要素が組み合わさってできている。 103 | 104 | - (A) headless GPU server上でGLXアプリを動かす 105 | 106 | GPUを使える仮想ディスプレイを作る。ソフトウェアレンダリングで十分な場合は、`xorg xvfb x11vnc`などで仮想ディスプレイ環境を作れるが、GPUを使いたい場合はNVIDIAドライバの機能を使う必要がある。 107 | - (B) docker上でX11サーバーを動かす 108 | 109 | ポピュラーな`DISPLAY` `/tmp/.X11-unix`を共有する方法ではなく、Xorgをコンテナ内で動かす方法。 110 | - (A+B) headless GPU server上のdocker上でX11サーバーとGLXアプリを動かす 111 | 112 | 上の2つを合わせれば完成。 113 | 114 | 順番に解説する。 115 | 116 | ### (A) run GLX apps on headless NVIDIA GPU server 117 | 118 | これに関しては解説がいろいろある。 119 | 120 | - [NVIDIA GPUで作るHeadless X11 Linux](https://www.slideshare.net/T_S/headless-x11-demo) 121 | - [Setting up a HW accelerated desktop on AWS G2 instances](https://medium.com/@pigiuz/setting-up-a-hw-accelerated-desktop-on-aws-g2-instances-4b58718a4541) 122 | - [EC2\(g2\.2xlarge\)でOpenGLを使う方法 \- ⊥=⊥](http://xanxys.hatenablog.jp/entry/2014/05/17/135932) 123 | - [How to run Unity on Amazon Cloud or without Monitor](https://towardsdatascience.com/how-to-run-unity-on-amazon-cloud-or-without-monitor-3c10ce022639) 124 | - [VirtualGL \| Documentation / Headless nVidia Mini How\-To](https://virtualgl.org/Documentation/HeadlessNV) 125 | - [Running without display and selecting GPUs \- CARLA Simulator](https://carla.readthedocs.io/en/latest/carla_headless/) 126 | 127 | 大まかな手順としては 128 | 129 | - Xorg, Nvidia Driverのインストール 130 | - XorgがGPUを使うようにconfを編集 131 | 132 | `nvidia-xconfig`を使うと、headless環境で仮想displayを使うためのXorg向けの設定を出力できる。しかしコマンド自体のオプションのマニュアルが不足しているので、release noteを読んで確認する必要がある。 133 | 134 | 今回はTesla T4を使う。`nvidia-xconfig --query-gpu-info`を見るとBUS idはPCI:0:4:0だったので 135 | 136 | ``` 137 | nvidia-xconfig \ 138 | -a \ 139 | --virtual=1280x1024 \ # 仮想スクリーンの解像度 140 | --allow-empty-initial-configuration \ # ディスプレイがなくてもXサーバーを起動する 141 | --enable-all-gpus \ # GPUを有効化 142 | --busid PCI:0:4:0 # GPUを見つけられるようにBUSIDを指定しておく 143 | ``` 144 | 145 | を実行した。これで出てきた/etc/X11/xorg.confはきちんと動いた。 146 | 147 | `--use-display-device=None`をつけるという記述があるが、[Version 410\.104\(Linux\)/412\.29\(Windows\) :: NVIDIA Tesla Documentation](https://docs.nvidia.com/datacenter/tesla/tesla-release-notes-410-104/index.html) によると410.104からサポートされなくなったらしく、つけると起動しなくなるので注意。 148 | 149 | 詳細についてはrepositoryの記述も読んでください。 150 | 151 | 152 | 153 | 154 | ### (B) X on Docker 155 | X11 GUIアプリケーションをdocker内で動かしたい時、いくつか選択肢がある。 156 | 157 | 1. hostのx11 socketの共有 or hostで建てているx serverのアドレスを環境変数DISPLAYで渡す 158 | 159 | docker run時に`-e DISPLAY=$DISPLAY`とか`-v /tmp/.X11-unix:/tmp/.X11-unix`とかを指定するのはこちらのアプローチ。やり方については検索すると出てくるので割愛。 160 | 161 | x11 clientだけをcontainer内で動かし、host上で動いているx11 serverに接続して描画してもらう。dockerからは描画命令だけが来るので、例えばGPUを使って実際に描画するのはx11 server側、つまりcontainer外になる。それ以前に、デスクトップ環境を作っていないサーバー上で動かす場合、そのhost上でまずX11サーバーをセットアップする必要がある。 162 | 163 | この方法でも、「ローカルのデスクトップ環境上で動かすが、ホストの環境を汚さないためにdocker内でGUIアプリを使いたい」場合や、「サーバーだけど直にX11をセットアップするのを厭わない」場合は十分。 164 | 3. docker内にx11 serverも建てる 165 | 166 | x11 client, server共にdocker内で動いている。このままでは画面が見えないが、VNCやスクリーンショットの形で出力する。この場合は、実際に描画処理をしているのもコンテナになる。 167 | 168 | - kubernetesやECSなどのコンテナベースのサービスを使っていて、Dockerコンテナの外側の環境に触れない場合 169 | - host上にX11サーバーをセットアップするのが面倒/できない場合 170 | 171 | だと、コンテナ内で完結する2の方法を取らざるを得なくなる。 172 | 173 | 例えば [DockerでXサーバを動かしてGUIを直接表示する \- くんすとの備忘録](https://kunst1080.hatenablog.com/entry/2018/03/18/225102) はこのアプローチを取っている。基本的にはコンテナ内にXserverとXclientを両方インストールし実行する。 174 | 175 | 176 | ### (A+B) GPU-enabled X server on Docker 177 | 普通のXアプリなら上の手順で良いが、OpenGLなどグラフィック用途でGPUを使うアプリケーションの場合、 178 | 179 | 1. hostのx11 socket共有 180 | 181 | [NVIDIA Docker で HW accelerated な OpenGL\(GLX\) を動かす\(2019 年版\) \- Qiita](https://qiita.com/syoyo/items/22a0db4d49495020f1bd) でも触れられているように、 [nvidia/opengl \- Docker Hub](https://hub.docker.com/r/nvidia/opengl) などを使う方法がある。繰り返しになるがこの場合だとレンダリングしているのはホスト側になる。 182 | 2. docker内にx11 serverも建てる 183 | 184 | この場合の手順について書かれた文章はほとんど見つけることができなかった。今回はこれをやりたい。 185 | 186 | コンテナ内にインストールされたXserverがGPUを扱えるように、X用のドライバをインストールする必要がある。 187 | 188 | #### グラフィック系ドライバのdocker内へのインストール 189 | docker内でNVIDIA GPUを扱いたいときは、nvidia-docker2を使うのが普通。これはホストのGPUのデバイスファイルとそのドライバをコンテナと共有し、GPUをコンテナ内側でも使えるようにする技術だが、公式にはCUDA系やOpenGLの一部のみをサポートしていて、グラフィック系のGLX・Xorgからのレンダリング・vulkan等に対応していない( https://github.com/NVIDIA/nvidia-docker/issues/631 )ため、XorgがNVIDIA-GPUを使うためのドライバやGLXのextensionはコンテナと共有されない。 190 | 191 | なので、nvidia-docker2の機能でGPUのデバイスファイルを使えるようにし、ドライバはコンテナ内部で1からインストールすることでGLXをコンテナ内で使えるようにできた。 192 | 193 | コンテナ内部でドライバをインストールするDockerfileとして、公式の [nvidia/driver \- Docker Hub](https://hub.docker.com/r/nvidia/driver) とその解説wiki [Driver containers \(Beta\) · NVIDIA/nvidia\-docker Wiki](https://github.com/NVIDIA/nvidia-docker/wiki/Driver-containers-(Beta)) がある。これはNVIDIAのドライバを公式からダウンロードして、インストールスクリプトを実行しているDockerfileだが、前述のようにX系のドライバをインストールを省略している。 https://gitlab.com/nvidia/driver/blob/master/ubuntu16.04/Dockerfile#L43 を見ると 194 | 195 | ``` 196 | --x-prefix=/tmp/null \ 197 | --x-module-path=/tmp/null \ 198 | --x-library-path=/tmp/null \ 199 | --x-sysconfig-path=/tmp/null \ 200 | ``` 201 | 202 | そこでXorgをインストールした後、ドライバインストール時にこのオプションをきちんと設定して、X用のグラフィックドライバをインストールさせる。これが終われば、ホストのGPUサーバー上でXorgを動かすのと全く同様に、dockerコンテナ内でXorgを(GPU込みで)動かすことができるようになる。 203 | 204 | あとは(A)と同じで、(A)のコマンドで作ったxorg.confをコンテナ内に設置して、`Xorg &`でサーバーを走らせれば動く。 205 | 206 | 207 | ## 各種ソフトウェア 208 | 209 | ### xorg 210 | X11サーバーの1つの実装。 211 | 212 | `Xorg :0`とするとサーバーが立ち上がる。 213 | 214 | 例えば`x11-apps`を入れて`DISPLAY=:0 xeyes`とすると目玉のテストアプリケーションが立ち上がる。 215 | 216 | [UbuntuでNVIDIAのディスプレイドライバが動作しない場合のチェック項目 \- Qiita](https://qiita.com/gm3d2/items/8346c76961d3fdb257b7) が参考になる。 217 | 218 | lspci | grep NVIDIA 219 | 220 | - 設定ファイル /etc/X11/xorg.conf 221 | - ログファイル /var/log/Xorg.0.log 222 | - /usr/lib/xorg/modules/drivers ドライバ 223 | - /usr/lib/xorg/modules/extensions glxのエクステンションなど 224 | 225 | 226 | ### テスト用X11アプリ 227 | - xeyes Xサーバーが動いているか? 228 | - glxgears, glxinfo GLXが使えるか? 229 | - vulkan-smoketest vulkanが使えるか? 230 | 231 | ### x11vnc 232 | 起動しているx11 serverの画面をそのままvncで飛ばすソフトウェア。実際のdisplayが繋がっている場合はその画面が、仮想displayの場合はその中身が転送される。 233 | 234 | ずっと起動しておく -forever 235 | 236 | ポート変更 x11vnc -rfbport 5566 237 | 238 | ### virtualGL 239 | - 公式 https://virtualgl.org/About/Background 240 | - わかりやすいarchlinuxの解説 https://wiki.archlinux.jp/index.php/VirtualGL 241 | 242 | 実際にアプリケーションを表示したいXサーバーのアドレスを`:0`、GPUにアクセスできるXサーバーのアドレスを`:1`とする。 243 | 244 | ``` 245 | DISPLAY=:0 VGL_DISPLAY=:1 vglrun glxgears 246 | ``` 247 | 248 | とした場合、アプリケーションのレンダリング命令が`:1`に行き、そのレンダリング結果が画像としてキャプチャされ、`:0`に送られる。これは通常通り 249 | 250 | ``` 251 | DISPLAY=:0 glxgears 252 | ``` 253 | 254 | とした時に、GPUにアクセスできないXサーバー(例えばこれはssh -Xで転送されたクライアントのXサーバーなど)側にレンダリング命令が来てGPUを活用できない状況をパフォーマンス面で改善できるが、実際に`:0`から見える結果は全く同じになる。 255 | 256 | ### xvfb 257 | 仮想ディスプレイを作るソフト。 258 | ただしGPUは使わない。ソフトレンダリングのみならこれで十分。 259 | 260 | ### nvidia-xconfig 261 | Xサーバーがnvidia gpuを使えるように 262 | 263 | nvidia-xconfig --query-gpu-info 264 | 265 | 266 | ### X周りの要素技術についてのまとめ 267 | [おっさんエンジニアの実験室: 12月 2016](http://ossan-engineer.blogspot.com/2016/12/) 268 | 269 | --------------------------------------------------------------------------------