WSL2(Ubuntu) + Dockerの環境を構築してkaggle公式のコンテナを動かす

## 概要

kaggleコンペのstarter notebookで使われているkeras-cvがwindows10で動かなかったので、必要にせまられてWSL2のUbuntu環境を構築することにした。また、せっかくなのでDocker Engineをインストールしてkaggle公式イメージを使えるようにした。その時の作業メモを残しておく。

## PC環境

このPCに、WSL2(Ubuntu) + Docker環境を構築する。
| 項目 | 値 |
|---|---|
| OS | Windows10 Pro 22H2 |
| CPU | Core i5-13500 |
| OSメモリ | 96 GB |
| GPU | GeForce RTX 2080 Ti |

## 準備

### Windowsターミナルのインストール
[公式サイト](https://learn.microsoft.com/ja-jp/windows/terminal/install)にしたがって、Windowsターミナルをインストールする。
必須ツールではないが、タブ操作でPowershellやWSLのubuntuを起動できるので便利。

Windowsターミナルのインストールをクリック
<img width="400" alt="Windowsターミナル" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/4b019812-fc95-6252-8f75-f313d6463d0c.png">

Microsoft Storeアプリの取得
<img width="600" alt="Microsoft Storeアプリから取得" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/bd5bf08a-ed3b-933e-e82c-3efcde86e2dd.png">

入手
<img width="400" alt="入手" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/f3952708-fe1c-18ae-a68e-9fac7565978a.png">

インストールが完了したら開く
<img width="400" alt="起動" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/f4eb90e2-55b0-2cd6-d56d-1a57863909e7.png">

次のWSLインストール作業以降、このWindowsターミナルを利用する。

## 環境構築

### WSL2のインストール

[公式サイト](https://learn.microsoft.com/ja-jp/windows/wsl/install)にしたがってWSL2をインストールする。

PowerShell上で以下のコマンドを実行する。必要な一式が自動でインストールされる
```powershell
wsl --install
```

インストールが完了したらシステムを再起動する
<img width="600" alt="インストール" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/8122744d-db1b-ae2a-314c-2bdad6ab30ab.png">

再起動するとUbuntuのインストールが自動で開始される。途中、作成するユーザーアカウントの入力を求められる。
<img width="600" alt="Ubuntu" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/a5615d05-f114-ebdb-0dda-608d07394370.png">

これでUbuntuのインストールは完了。
インストールしたUbuntuは、Windowsターミナルのタブから起動することができる
<img width="400" alt="Ubuntu" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/f5ca00c8-c88a-5cb7-e41c-44ac6b40e337.png">

### Ubuntuのリソース設定変更

Ubuntuに割り当てられるメモリサイズはデフォルトでホスト（Windows）の半分らしい。必要に応じて、設定ファイルを作成してリソース設定を変更する。私は[こちら](https://zenn.dev/karaage0703/articles/d38e17bd6efbaa)を参考にした。

.wslconfigファイルの作成場所（Windows側）
```
C:\Users\[ユーザ名]\.wslconfig
```

設定例：メモリを80GB割り当て
```config
[wsl2]
memory=80GB
```

設定ファイルの内容を反映させるため、PowerShell上でwslをシャットダウンする
```powershell
wsl --shutdown
```

メモリが80GBに増えたことを確認

<img width="600" alt="topコマンド" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/541d901c-2d87-a43f-6dc1-6da6fe61f72e.png">


なお、メモリ以外のリソース設定も変更できる。[こちら](https://ascii.jp/elem/000/004/044/4044122/2/)が参考になる。


### Docker Engineインストール

[公式Doc](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository)にそってDocker Engineをインストールする。
私は、公式DocのInstall using the Apt repository　の内容をそのまま実行した。

DockerのAptリポジトリをセット
```bash
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update 
```

Dockerパッケージのインストール
```
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

インストール完了後、hello-worldコンテナを起動して動作確認を行う。
```bash
sudo docker run hello-world
```

あと、sudoをつけずにdockerコマンドを実行できるよう、dockerグループにユーザ追加を行う。
```bash
# sudo usermod -aG docker $USER
sudo usermod -aG docker <ユーザ名>
```

### NVIDIA Container Toolkitのインストール

コンテナの中でNvidia GPUを利用するため、NVIDIA Container Toolkitをインストールする。

[公式ガイド](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)にしたがって、Installing with Aptの内容をそのまま実行する。


リポジトリの設定
```bash
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \
  && \
    sudo apt-get update

sudo apt-get install -y nvidia-container-toolkit
```

NVIDIA Container Toolkitパッケージのインストール
```bash
sudo apt-get install -y nvidia-container-toolkit
```

### Dockerイメージの取得

[github](https://github.com/Kaggle/docker-python)を参考に、kaggle公式イメージを取得する。

```bash
# gpuのイメージ取得コマンド
docker pull gcr.io/kaggle-gpu-images/python

# cpu onlyのイメージ取得コマンド
docker pull kaggle/python
```

リポジトリにイメージが登録されたことを確認する
```bash
docker images
```

<img width="600" alt="docker images" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/dfd26dfc-6d03-946d-c8af-89af92ba2cf1.png">


### 動作確認

コンテナを作成し、動作確認を行う。

```bash
# コマンド例
docker run -it --gpus all -h "kgl_gpu1" --rm -p 80:8888 -v /mnt/c/work:/mnt/work --name kgl_gpu1 gcr.io/kaggle-gpu-images/python /bin/bash
# -i:対話形式で操作できるようにする
# -t:疑似tty端末を割り当てる
# --gpus:コンテナ内で利用するgpuデバイスを指定
# -h：コンテナのホスト名の指定
# --rm：終了時にコンテナを削除
# -p：ポートフォワードの設定（不要かも）。 <ホスト側ポート>:<コンテナ側ポート>
# -v：ディスクのマウント設定 <ホスト側ディレクトリ>:<コンテナ内マウントポイント>。複数指定も可能
# --name：起動するコンテナーに名前を付ける（省略すると、適当な名前がつくっぽい）

```

コンテナ内でnvidia-smiコマンドを実行し、gpuが認識されていることを確認する
<img width="600" alt="nvidia-smi" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238113/b5f3c4f4-576d-0431-b764-0a3f8b056f83.png">

おしまい。

## 参考

### Windowsターミナル
- Windows ターミナルをインストールしてセットアップを開始する
  https://learn.microsoft.com/ja-jp/windows/terminal/install

### WSL2
- WSL を使用して Windows に Linux をインストールする方法
  https://learn.microsoft.com/ja-jp/windows/wsl/install


### WSLのUbuntuリソース設定
- WSL2/Ubuntu/Raspberry Piでのメモリ不足を解消する
  https://zenn.dev/karaage0703/articles/d38e17bd6efbaa
- WSL2の2つの設定ファイル「.wslconfig」と「wsl.conf」
  https://ascii.jp/elem/000/004/044/4044122/2/

### Docker
- Install Docker Engine on Ubuntu
  https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository
- よく使うDockerコマンド
  https://qiita.com/noralife/items/18301143c20cc5172c56
- 【Docker】Dockerでホストのディレクトリをマウントする
  https://qiita.com/Yarimizu14/items/52f4859027165a805630

### NVIDIA Container Toolkit
- Installing the NVIDIA Container Toolkit
  https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html

- NVIDIA Container Toolkit (NVIDIA Docker) は何をしてくれるか
  https://qiita.com/tkusumi/items/f275f0737fb5b261a868

ほかにも参考にしたサイトがいくつかあったが、忘れてしまった。思い出したら追記するつもり。