GCP+Docker+GPUでrosを動かす (1) ~ GCPでGPUとVNCを用いた環境の構築 ~

この記事はGPUを搭載したPCを持っていない人で、GPUを使ってrosのGazeboを用いた機械学習 (主に強化学習)をしたいという人向けに書きました。

今回は、GCPを用いてインスタンスを作成し、そのインスタンスのデスクトップ環境にDockerのGUIを出すところまでをやります。

#GCPとは
GCPとは元々Google製のPaaSとして知られる Google App Engine を中心に、EC2相当の Google Compute Engine、NoSQLであるCloud Datastore、ビッグデータ解析ツールのBigQueryなど、様々な製品をひとまとめにした環境です。これを用いた仮想PC環境を構築することでGPUを持っていない人でもGPUを用いた作業ができるようになります。

## GCPでインスタンスを作成
[こちらの記事](https://qiita.com/SXDSIR2020/items/060806d9fc4366c58d40)を参考に作業を進めてください。
今回作成したインスタンスのスペックは以下の通りです。
コア数：8
メモリ数：52GB
GPU：Tesla K80

## VNC環境の構築
インスタンスを作成したら、以下のコマンドを実行する。

```
$ sudo apt update
$ sudo  apt upgrade -f -y
$ sudo apt install -y \
     gnome-core \
     gnome-panel \
     vnc4server
```
全てのインストールが完了したら、`vncserver`を起動する。(初回起動時にパスワードを登録する)

```
$ vncserver
```
その後、`vncserver`を一旦停止し、設定を変更する。

```
$ vncserver -kill :1
$ vim .vnc/xstartup
```
xstartupの編集内容
unset SESSION_MANAGERの#を外します。
[ -x /etc/vnc/xstartup] 以下の全ての行の先頭に#を付けます。
一番下に以下の設定を追加します。
metacity &
gnome-settings-daemon &
gnome-panel &

これでVNCサーバーから起動できるようになる。
#Dockerのインストール
以下のコマンドを実行してDockerをインストールする。
 まずは必要なパッケージ類をインストールする。

```
$ sudo apt update
$ sudo apt install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
```
続いて GPG 鍵をインストールする。

```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
```
そしてリポジトリを追加する。

```
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```
パッケージインデックスを更新したらDocker CE関連のパッケージをインストールする。

```
$ sudo apt update
$ sudo apt install -y docker-ce
```
インストールできたら `docker version` コマンドでクライアントとサーバが正常に稼働していることを確認しておく。

```
$ docker version
```
これでDockerのインストールが完了する。
##NVIDIAのドライバインストール
まずはホストに NVIDIA の提供するグラフィックスドライバをインストールする。 なお、CUDA はバージョンによってサポートしているグラフィックスドライバのバージョンが異なる。 そのため、利用したい CUDA のバージョンに合わせてインストールするバージョンを選ばなければいけない。
以下の手順でコマンドを実行します。

```
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt update
```
これでパッケージシステムからインストールできるグラフィックスドライバが増える。

```
$ apt-cache search nvidia-driver
$ sudo apt-get -y install ubuntu-drivers-common
$ ubuntu-drivers devices
```
推奨 (recommended) になっているドライバに関しては以下のようにインストールできる。

```
$ sudo ubuntu-drivers autoinstall
```
続いては今回のメインとなる NVIDIA-Docker2 をインストールする。
まずは GPG 鍵をインストールしておく。

```
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
```
続いて NVIDIA-Docker2 のリポジトリを登録する。

```
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list
```
パッケージインデックスを更新したら NVIDIA-Docker2 をインストールする。

```
$ sudo apt-get update
$ sudo apt-get -y install nvidia-docker2
```
インストールできたら Docker のデーモンを再起動する。

```
$ sudo pkill -SIGHUP dockerd
```
これで NVIDIA-Docker2 を利用する準備ができた。
以下のコマンドで動作確認をする。

```
$ sudo docker run --runtime=nvidia --rm -it nvidia/cuda:10.1-cudnn7-devel /bin/bash
```

```
root@78bc892cec27:/# nvidia-smi
Tue Dec 24 15:18:24 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.44       Driver Version: 440.44       CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 00000000:00:04.0 Off |                    0 |
| N/A   35C    P0    67W / 149W |      0MiB / 11441MiB |    100%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
```
確認出来たらコンテナを終了する。

```
root@78bc892cec27:/# exit
```

#実行
`VNCserver`を起動する。

```
$ vncserver
```
私の場合、VNC Viewer for Google Chromeを用いています。
その後、[このgit](https://github.com/ikeyasu/docker-reinforcement-learning)に従って、以下のコマンドを実行する。

```
$ sudo docker run --runtime=nvidia -it -p 6080:6080 ikeyasu/reinforcement-learning:latest
```
VNC Viewer for Google Chromeで http://localhost:6080 に接続するとブラウザ上にターミナルが表示される。
ここに以下のコマンドを入力するとroboschoolのサンプルプログラムが動く。

```
$ python3 $ROBOSCHOOL_PATH/agent_zoo/demo_race2.py
```

![スクリーンショット (32).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419891/103d86ca-7fb7-a366-044f-99fe0b2da542.png)

最終的には、上記の図のようにGCPのVMを動かしているVNC上で動いているDockerのguiブラウザにroboschoolが実装されます。
ここまでできたので次回はrosでgazeboをやってみようかと思う。