WSLで良くあるトラブルと対処方法

# 1.この記事の内容

WSL(Windows Subsystem for Linux)を使っていて良くあるトラブルとその対処方法を紹介します．
新たなトラブルが生じた際は，随時，追記していきたいと思います．

## 1-1.使用環境

* Windows 10
* Windows Subsystem for Linux 2
  * Ubuntu 18.04.5 LTS

# 2.良くあるトラブルと対策

## 2-1.PowerShellからWSLへログインできない／突如WSLが落ちる

PowerShellからWSLを起動後，エラーメッセージ等が表示されることなくログインできなかったり，突如強制ログアウトされたりする現象が生じることがあります．
原因は不明ですが，下記の手順でLxssManagerを起動することで，問題を解消できています．

1. PowerShellを管理者権限で起動
1. 下記コマンドを実行して， LxssManagerを起動
<pre>
> net start LxssManager
</pre>
※LxssManagerが落ちていない場合もあるようで，その場合はLxssManagerをstop後にstartする
<pre>
> net stop LxssManager
> net start LxssManager
</pre>

## 2-2.WSLからnvidia-dockerが起動できない（GPUに接続できない）

WSLからnvidia-dockerのrunコマンド実行時に下記のようなメッセージが表示され，Dockerコンテナを起動できないことがあります．
※エラーメッセージ全文は控えられず，一部のみです．
<pre>
docker: Error response from daemon: OCI runtime create failed: container_linux.go ～
</pre>

WSLからnvidia-dockerでGPU接続する場合には，標準のドライバではなく，[CUDA on Windows Subsystem for Linux (WSL) - Public Preview](https://developer.nvidia.com/cuda/wsl)のインストールが必要ですが，ドライバの自動アップデートで，WSL非対応のドライバに更新されてしまう場合があるようです．

[CUDA on Windows Subsystem for Linux (WSL) - Public Preview](https://developer.nvidia.com/cuda/wsl)からドライバのダウンロード及びアップデートを行うことで，問題を解消できています．

# 2-3.WSLから起動したDockerコンテナ上のWebサーバにlocalhostで接続できない

ホストマシンのlocalhostとDockerコンテナのlocalhostが異なる為，アドレス解決ができないことが要因です．
下記2点の対応で問題を解消できます．

1. docker run時に-pオプションでポートを指定する
2. サーバを"0.0.0.0"でLISTENする

## 2-3-1.課題概要
![issue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983907/b3ed5c35-9cf5-7357-8a5c-972ca6c10dc7.png)

## 2-3-2.解決方法概要
![solution.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983907/4dcc09a7-5e7d-b87c-dab4-70f2afe33459.png)

## 2-3-3.サーバを"0.0.0.0"でLISTENする方法(例)

### Gulp
gulpfile.jsに下記行を追加する．
<pre>
host: "0.0.0.0"
</pre>

具体例：
<pre>
// Local server pointing on build folder
const connect = () => {
        return plugins.connect.server({
                root: config.destDir,
                host: "0.0.0.0",
                port: config.port || 3333,
                livereload: true
        });
};
</pre>

## 2-4.mkfifoでFIFOを生成できない

WSLでFIFOを生成する際に，生成先のディレクトリをWindowsファイルシステムとすると下記のエラーが発生しFIFOの生成に失敗します．

```
$ mkfifo /mnt/c/Users/<user name>/fifo_test
mkfifo: cannot create fifo '/mnt/c/Users/<user name>/fifo_test': Operation not supported
```

```~/``` や ```/tmp``` などLinuxシステムの領域にのみ生成可能です．

```
$ cd ~
$ mkfifo fifo_test
$ ls
fifo_test
```

## 2-5.ネットワークに接続できない

WSL2で下記のようにネットワークに接続できない場合，```/etc/resolv.conf```に```nameserver 8.8.8.8```を指定すると解決しました．
8.8.8.8はGoogleが公開しているPublic DNSです．

8.8.8.8でなくても設定によっては接続できる場合もあるようですが，Windows Updateなどの更新でまれに変化が生じるようです．

### 接続できない場合の例

```
$ host google.com
;; connection timed out; no servers could be reached
```

### 接続できる場合の例

```
$ host google.com
google.com has address 142.250.207.110
google.com has IPv6 address 2404:6800:400a:805::200e
google.com mail is handled by 40 alt3.aspmx.l.google.com.
google.com mail is handled by 10 aspmx.l.google.com.
google.com mail is handled by 20 alt1.aspmx.l.google.com.
google.com mail is handled by 30 alt2.aspmx.l.google.com.
google.com mail is handled by 50 alt4.aspmx.l.google.com.
```

## 2-6.Dockerが起動できない(Ubuntu 22.04)

WSL上のUbuntu 22.04でDockerが起動しない問題が生じました．  
もし，18.04や20.04でも同様の事象が起きた方は参考にしてみてください．

```shell:問題の事象
$ sudo service docker start
 * Starting Docker: docker                                                                                       [ OK ]
$ sudo service docker status
 * Docker is not running
```

### 2-6-1.まず解決策

legacyのiptablesを使用することで解決しました．

```shell
$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
$ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
$ sudo service docker start
 * Starting Docker: docker                                                                                       [ OK ]
$ sudo service docker status
 * Docker is running
```

### 2-6-2.nvidia-docker インストール手順

NVIDIA公式ドキュメント[4.2. Running Existing GPU Accelerated Containers on WSL 2](https://docs.nvidia.com/cuda/wsl-user-guide/index.html#ch05-running-containers)に従い設定

```shell
$ curl https://get.docker.com | sh 
$ 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
$ sudo apt-get update
$ sudo apt-get install -y nvidia-docker2
```

### 2-6-3.この手順だけではDockerが起動できない

```sudo service docker start```では```[ OK ]```と表示されるも，直後の```sudo service docker status```で起動できていません．

```shell
$ sudo service docker stop
 * Docker already stopped - file /var/run/docker-ssd.pid not found.
$ sudo service docker start
 * Starting Docker: docker                                                                                       [ OK ]
$ sudo service docker status
 * Docker is not running
```

### 2-6-4.ログを確認

エラー箇所を見ると，iptablesで止まっています．

```shell
$ cat /var/log/docker.log
～略～
failed to start daemon: Error initializing network controller: error obtaining controller instance: unable to add return rule in DOCKER-ISOLATION-STAGE-1 chain:  (iptables failed: iptables --wait -A DOCKER-ISOLATION-STAGE-1 -j RETURN: iptables v1.8.7 (nf_tables):  RULE_APPEND failed (No such file or directory): rule in chain DOCKER-ISOLATION-STAGE-1
 (exit status 4))
time="2022-05-03T07:59:11.765158700+09:00" level=warning msg="grpc: addrConn.createTransport failed to connect to {unix:///var/run/docker/containerd/containerd.sock  <nil> 0 <nil>}. Err :connection error: desc = \"transport: Error while dialing dial unix:///var/run/docker/containerd/containerd.sock: timeout\". Reconnecting..." module=grpc
$
```

### 2-6-5.Dockerではiptables 1.8系がうまく動かない

[Docker doesn't work with iptables v1.8.1](https://github.com/moby/moby/issues/38099)に記載の通り，Dockerではiptables 1.8系が動作しないようで，Ubuntu 22.04でも解決していないようです．

### 2-6-6.【続報】この問題がPostgreSQLサーバへのアクセスにも影響していた

WSLの環境を更新した際に，PostgreSQLサーバへの接続でタイムアウトが発生しました．
新しい環境ではDockerサービスが起動し，Docker buildも通ったのでパッケージの更新などにより解決したものかと思いましたが，そうではなかったようです．

```shell:PostgreSQLエラーログ
django.db.utils.OperationalError: connection to server at "db" (172.19.0.2), port 5432 failed: Connection timed out
        Is the server running on that host and accepting TCP/IP connections?
```

## 2-7.docker build時にネットワークに接続できない

docker buildでパッケージ等をインストールする際に，ネットワーク接続が確立できない時があります．
突然生じた問題ですが，```/etc/default/docker```で```DOCKER_OPTS```のコメントアウトを外して，```sudo service docker restart```すると解決できました．

### 2-7-1.エラー内容
```
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt:
#0 7.746 WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f8387022f70>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/django/
#0 14.49 WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f838703c280>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/django/
#0 21.71 WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f838703c4f0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/django/
#0 29.99 WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f838703c6a0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/django/
#0 40.23 WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f838703c850>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/django/
```

### 2-7-2.対策詳細（DOCKER_OPTSの設定方法）

```DOCKER_OPTS```のコメントアウトを外し，```$ sudo service docker restart```で設定変更を反映します．

```
 #DOCKERD="/usr/local/bin/dockerd"

 # Use DOCKER_OPTS to modify the daemon startup options.
-#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"
+DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"

 # If you need Docker to use an HTTP proxy, it can also be specified here.
 #export http_proxy="http://127.0.0.1:3128/"
```


# 3.さいごに

DeepLearning環境としてWSLを活用する中で遭遇するトラブルと対策をまとめてきました．
Insider PreviewはWindowsのアップデートが頻繁に生じる為，新たなトラブルも生じる可能性ありますが，これまで活用してきた中では思っていたほどトラブルは少ない印象です．

# 4.関連リンク

* [2-1.PowerShellからWSLへログインできない／突如WSLが落ちる](#2-1.PowerShellからWSLへログインできない／突如WSLが落ちる)
  * [CUDA on WSL User Guide](https://docs.nvidia.com/cuda/wsl-user-guide/index.html)
  * [CUDA on Windows Subsystem for Linux (WSL) - Public Preview](https://developer.nvidia.com/cuda/wsl)
* [2-2.WSLからnvidia-dockerが起動できない（GPUに接続できない）](#2-2.WSLからnvidia-dockerが起動できない（GPUに接続できない）)
  * [【2020/12月ver】WSL2でCUDAを利用するなら自動アップデートに気を付けようという話とその対処法](https://qiita.com/yasudadesu/items/ca15e36137b00dc8d59a)
* [2-3.WSLから起動したDockerコンテナ上のWebサーバにlocalhostで接続できない](#2-3.WSLから起動したDockerコンテナ上のWebサーバにlocalhostで接続できない)
  * [docker上のアプリにlocalhostでアクセスしたらERR_EMPTY_RESPONSEが出る](https://qiita.com/amuyikam/items/01a8c16e3ddbcc734a46#port-forwarding-1270018000---17217098000)
  * [WSL2のDockerでWebサーバーを立てて、Widnows10のブラウザからアクセスする方法](https://qiita.com/MCK9595/items/ab27b1b50b47021aa423)
  * [NodeやGulpでhost: "0.0.0.0" を指定してサーバーを立ち上げたとき、 listen EADDRINUSE というエラーが出た場合の対応](https://qiita.com/colorrabbit/items/f034db661a42ecadae4b)
* [2-5.ネットワークに接続できない](#2-5.ネットワークに接続できない)
  * [Google Public DNS](https://ja.wikipedia.org/wiki/Google_Public_DNS)
* [2-6.Dockerが起動できない](#2-6.Dockerが起動できない)
  * [WSLでDockerが動かないときに試したこと](https://qiita.com/gyojir/items/d2b7e4974c7ac3cb459a)
  * [WSL2 (Ubuntu 20.04) + docker が動作しなかったことと解決策](https://qiita.com/TsuyoshiUshio@github/items/2530876fc81e8afd7c82)
* [2-7.docker build時にネットワークに接続できない](#2-7docker-build時にネットワークに接続できない)
  * [Temporary failure in name resolution [Errno -3] with Docker](https://stackoverflow.com/questions/44761246/temporary-failure-in-name-resolution-errno-3-with-docker)