LoginSignup
10
15

More than 1 year has passed since last update.

WSL2 + Dockerのメモ

Last updated at Posted at 2021-11-24

想定環境

  • WSL2 on Windows11
  • with NVIDIA GPU

Install

WSL2 (Ubuntu) のインストール

パワーシェル(管理者権限)
wsl --install -d Ubuntu-20.04
  • イメージ置き場
    • C:\Users\iwatake\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState
  • WindowsからWSLファイルへのアクセス
    • \\wsl.localhost\Ubuntu-20.04
  • WSLからWindowsファイルへのアクセス
    • /mnt/c/
  • WSLのGUIアプリを実行する場合、Windows側にX表示用アプリ (VcXsrvなど) は不要。だけど、Docker上のGUIアプリを実行する場合は必要っぽい

VSCode

  • Windows上のVSCodeにms-vscode-remote.vscode-remote-extensionpack をインストールしておく
  • WSL上で、sudo apt install wget ca-certificates しておく

WindowsのVSCodeからWSL上のDockerコンテナ内のファイルにアクセスする

  • VSCodeをWindowsで開く
  • Remote Explorer -> WSL Targets -> Ubuntu-20.04(WSL) -> Connect to WSL
  • Remote Explorer -> Containers -> Target container -> Attach to container

NVIDIA CUDA in WSL のインストール (optional)

Dockerのインストール

WSL
# Docker
curl https://get.docker.com | sh
sudo usermod -aG docker $USER

# NVIDIA Container Toolkit (optional)
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
curl -s -L https://nvidia.github.io/libnvidia-container/experimental/$distribution/libnvidia-container-experimental.list | sudo tee /etc/apt/sources.list.d/libnvidia-container-experimental.list

sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo service docker restart
sudo service docker start

Docker よく使うコマンド

管理コマンド

基本
sudo service docker start    # WSLの場合、毎回startが必要
# docker image ls
docker images
# docker container ls -a
docker ps -a
docker rm  MY_CONTAINER_NAME
docker rmi IMAGE_NAME
保存(コンテナからイメージ作成)
docker commit MY_CONTAINER_NAME my_new_image_from_container
docker save my_new_image_from_container -o my_new_image_from_container.tar

イメージの取得

WSL
docker pull ubuntu:20.04

イメージのビルド

Dockerfile
FROM ubuntu:20.04

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
  build-essential \
  cmake \
  curl \
  git \
  libopencv-dev \
  nano
WSL
docker build ./ -t cpp_opencv_image
# docker run --rm -it cpp_opencv_image

コンテナの生成と起動

同じコンテナを使いたい場合

WSL
# docker run -itd --name=MY_CONTAINER_NAME ubuntu:20.04
docker create -it --name=MY_CONTAINER_NAME ubuntu:20.04
docker start MY_CONTAINER_NAME
docker exec -it MY_CONTAINER_NAME bash
docker stop MY_CONTAINER_NAME
  • メモ
    • createでの-it 指定はコンテナの標準入出力、ターミナルの設定。docker attach MY_CONTAINER_NAME 用。また、これがないとstartしてもすぐに終了してしまう。
    • execでの-it は新規に作成するbashプロセス用の設定

1回だけ動かす(コンテナは毎回削除)

WSL
docker run --rm -it  ubuntu:20.04
docker run --rm ubuntu:20.04 /bin/echo "Hello World"

よく使うオプション

WSL
docker create  -v /mnt/c/iwatake/devel:/root/devel -v /etc/localtime:/etc/localtime:ro -e DISPLAY="192.168.1.2:0"  -w /root/ -p 8888:8888 -it --name=MY_CONTAINER_NAME ubuntu:20.04
docker run --rm -v /mnt/c/iwatake/devel:/root/devel -v /etc/localtime:/etc/localtime:ro -e DISPLAY="192.168.1.2:0"  -w /root/ -p 8888:8888 -it  ubuntu:20.04

Docker 例

GPUを見れるようにだけしたい

WSL
docker run --name=ubuntu_gpu_0 -it --gpus=all ubuntu:20.04
# docker run --name=ubuntu_gpu_0 -it --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0 ubuntu:20.04

TensorFlow + Jupyter

WSL
docker run -it --rm -v /mnt/c/iwatake/devel:/home/jovyan/devel -e DISPLAY="192.168.1.2:0" -p 8888:8888 jupyter/tensorflow-notebook

NGC: TensorFlow + Jupyter

WSL
docker run --gpus all -it --rm -v /mnt/c/iwatake/devel:/workspace/devel -e DISPLAY="192.168.1.2:0" -p 8888:8888 nvcr.io/nvidia/tensorflow:21.11-tf2-py3 jupyter-lab

train_mnist.ipynb
# https://www.tensorflow.org/guide/gpu?hl=ja
import tensorflow as tf

print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

# with tf.device('/CPU:0'):
with tf.device('/GPU:0'):
    model = tf.keras.models.Sequential([
      tf.keras.layers.Flatten(input_shape=(28, 28)),
      tf.keras.layers.Dense(128, activation='relu'),
      tf.keras.layers.Dropout(0.2),
      tf.keras.layers.Dense(10),
      tf.keras.layers.Softmax()
    ])
    loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
    model.compile(optimizer='adam',
                  loss=loss_fn,
                  metrics=['accuracy'])
    model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test,  y_test, verbose=2)

NGC: その他

WSL
docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark  
docker run --gpus all -it --rm -v /mnt/c/iwatake/devel/:/workspace/devel -e DISPLAY="192.168.1.2:0" nvcr.io/nvidia/tensorrt:21.11-py3
docker run --gpus all -it --rm -v /mnt/c/iwatake/devel/:/workspace/devel -e DISPLAY="192.168.1.2:0" nvcr.io/nvidia/cuda:11.4.2-devel-ubuntu20.04
  • メモ
    • TensorRTはONNXモデル変換がうまくいかない (変換中に、 GPU error during getBestTactic: xxx : invalid argument エラーが出てフリーズする)。けど、サンプルのmnixt.onnxは変換可能なので、モデル依存か?

Docker その他

Docker内のワークスペースをVSCodeで開く

  • Windows上でDocker Desktopを入れていたら、Remote Explorer -> Containersで開けるはず
  • WSL内にdocker-ceをインストールしている場合、WSL上で、code . を開いてから、Remote Explorer -> Containersで開けるはず
    • 開きたいコンテナを選んで、Attach Container。すると新Windowsが開くので、OpenFolder

GUI出力について

  • WSL2のGUIは何もしないでも出力される (Windows11の場合)
  • WSL2 + DockerのGUIはX11フォワーディングが必要
    • DISPLAY環境変数を自分のIPアドレスに設定する
    • Xサーバソフトが必要。vcxsrvか、MobaXterm
  • 描画速度はどれも大差なかった (1280x720のcv::Matをcv::imshow, waitkeyした場合)
    • VS2019(Windows11): 2.5 ms
    • WSL2: 1.5ms
    • WSL2 + Docker: 1.6m
    • ※Windows10の時はもっと遅かった気がする

WSL上で、TensorRT環境を整える

  • CUDAはNGC環境で動いた
  • だけど、TensorRTはNGC環境だと動かないので、しょうがないのでWSL上で直接構築する
  • WSL上でもうまく動かなかった。。。

WSL上で、CUDAのインストール

WSL
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.4.0/local_installers/cuda-repo-wsl-ubuntu-11-4-local_11.4.0-1_amd64.deb
sudo dpkg -i cuda-repo-wsl-ubuntu-11-4-local_11.4.0-1_amd64.deb
sudo apt-key add /var/cuda-repo-wsl-ubuntu-11-4-local/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda

sudo ldconfig
パワーシェルとWSL
wsl -e /bin/bash
cd /mnt/c/Windows/System32/lxss/lib
ln -s libcuda.so.1.1 libcuda.so.1
ln -s libcuda.so.1.1 libcuda.so
  • 下記を毎回実行するか、~/.bashrc に追加する
WSL
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"

WSL上で、cuDNNのインストール

WSL
tar -xvf cudnn-11.4-linux-x64-v8.2.4.15.tgz
sudo cp cuda/include/cudnn*.h /usr/local/cuda/include 
sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda/lib64 
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*

WSL2上で、TensorRTのインストール

WSL
version="8.2.1.8"
arch=$(uname -m)
cuda="cuda-11.4"
cudnn="cudnn8.2"
tar xzvf TensorRT-${version}.Linux.${arch}-gnu.${cuda}.${cudnn}.tar.gz
  • 下記を毎回実行するか、~/.bashrc に追加する
WSL
version="8.2.1.8"
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/TensorRT-${version}/lib
export TensorRT_ROOT=~/TensorRT-${version}

WSL2上で、USB接続のWebCameraを使う (usbipd使用バージョン)

一度だけやればよいこと

WSL
sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev autoconf libudev-dev libtool
uname -r
# 5.10.16.3-microsoft-standard-WSL2

sudo git clone https://github.com/microsoft/WSL2-Linux-Kernel.git /usr/src/5.10.16.3-microsoft-standard
cd /usr/src/5.10.16.3-microsoft-standard

sudo git checkout linux-msft-wsl-5.10.16.3

sudo cp /proc/config.gz config.gz
sudo gunzip config.gz
sudo mv config .config

sudo make menuconfig

### ↓↓↓ 変更内容
Device Drivers->USB support[*]
Device Drivers->USB support->Support for Host-side USB[M]
Device Drivers->USB support->Enable USB persist by default[*]
Device Drivers->USB support->USB Modem (CDC ACM) support[M]
Device Drivers->USB support->USB Mass Storage support[M]
Device Drivers->USB support->USB/IP support[M]
Device Drivers->USB support->VHCI hcd[M]
Device Drivers->USB support->VHCI hcd->Number of ports per USB/IP virtual host controller(8)
Device Drivers->USB support->Number of USB/IP virtual host controllers(1)
Device Drivers->USB support->USB Serial Converter support[M]
Device Drivers->USB support->USB Serial Converter support->USB FTDI Single Port Serial Driver[M]
Device Drivers->USB support->USB Physical Layer drivers->NOP USB Transceiver Driver[M]
Device Drivers->Network device support->USB Network Adapters[M]
Device Drivers->Network device support->USB Network Adapters->[Deselect everything you don't care about]
Device Drivers->Network device support->USB Network Adapters->Multi-purpose USB Networking Framework[M]
Device Drivers->Network device support->USB Network Adapters->CDC Ethernet support (smart devices such as cable modems)[M]
Device Drivers->Network device support->USB Network Adapters->Multi-purpose USB Networking Framework->Host for RNDIS and ActiveSync devices[M]

Device Drivers > Multimedia support[*]
Device Drivers > Multimedia support > Media drivers > Media USB Adapters[*]
Device Drivers > Multimedia support > Media drivers > Media USB Adapters >  USB Video Class (UVC) [M]
Device Drivers > Multimedia support > Media drivers > Media USB Adapters >  USB Video Class (UVC) > UVC input events device support [*]
### ↑↑↑ 変更内容

sudo make -j 12 && sudo make modules_install -j 12 && sudo make install -j 12
sudo cp /usr/src/5.10.16.3-microsoft-standard/vmlinux /mnt/c/Users/iwatake/.
  • ビルドしたカーネルを使用するように設定する
C/Users/iwatake/.wslconfig
[WSL2]
kernel=C:\\Users\\iwatake\\vmlinux
  • 一度wsl --shutdown する

  • WSL上でUSB/IP用のユーザースペースツールのインストール (この手順は不要かも)

WSL
sudo apt install linux-tools-5.4.0-77-generic hwdata
sudo visudo

### ↓↓↓ 変更内容
# Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
Defaults        secure_path="/usr/lib/linux-tools/5.4.0-77-generic:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
### ↑↑↑ 変更内容
  • 一度wsl --shutdown する

毎回必要なこと

  • 必要なモジュールをロードする。/dev/video* を使えるようにする
sudo modprobe usbcore
sudo modprobe usb-common
sudo modprobe hid-generic
sudo modprobe hid
sudo modprobe usbnet
sudo modprobe cdc_ether
sudo modprobe rndis_host
sudo modprobe usbserial
sudo modprobe usb-storage
sudo modprobe cdc-acm
sudo modprobe ftdi_sio
sudo modprobe usbip-core
sudo modprobe vhci-hcd

sudo modprobe uvcvideo
# sudo modprobe videobuf2-v4l2
# sudo modprobe videobuf2-memops
# sudo modprobe videobuf2-common
# sudo modprobe videobuf2-vmalloc

sudo chmod 777 /dev/video*
PowerShell(管理者)
usbipd wsl list
#PS C:\Users\iwatake> usbipd wsl list
# BUSID  DEVICE                                                        STATE
# 1-8    USB 入力デバイス, WinUsb デバイス                                       Not attached
# 1-12   USB 入力デバイス                                                    Not attached
# 1-13   USB オーディオ デバイス, USB ビデオ デバイス                                  Not attached
# 2-2    USB 入力デバイス                                                    Not attached

usbipd wsl attach --busid 1-13
usbipd wsl detach --busid 1-13

WSL2 + Docker上で、USB接続のカメラを使う

  • WSL2上でUSBカメラが使用できる状態で、--device=/dev/video0:/dev/video0 オプションをつけてコンテナを作る
    • docker create -v /mnt/c/iwatake/devel:/root/devel -e DISPLAY="192.168.1.2:0" --device=/dev/video0:/dev/video0 -it --name=cpp_opencv cpp_opencv_image
10
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
15