VSCodeのDocker拡張機能で Failed to connect. Is Docker installed and running? エラーになる場合の対処法

Docker Desktop for WindowsをWSL2のUbuntuから利用した際、リモート接続したVSCodeのDocker拡張機能から接続できない場合の対処法について。

## 環境
* ホストOS：Windows 10
* ゲストOS：Ubuntu 20.04（WSL2）
* Docker：Docker Desktop for Windows（version 19.03.12, build 48a66213fe）
    * ダッシュボードの設定の
        * General > Expose daemon on tcp://localhost:2375 without TLS：**無効（チェックなし）**
        * Resources > WSL Integration：開発環境のあるUbuntuに対して有効
    * UbuntuにDockerはインストールされていない
    * 開発環境はUbuntuのファイルシステム上にある
* VSCode：v1.48.0
    * Docker拡張機能（Ubuntuにインストール、v1.4.1）

## 発生したエラー
Docker拡張機能のビューで

```
Failed to connect. Is Docker installed and running? (ECONNREFUSED 127.0.0.1:2375)
```

## 解決法

Docker拡張機能の[README](https://github.com/microsoft/vscode-docker#installation)によれば

> On Linux, you should [enable rootless Docker](https://docs.docker.com/engine/security/rootless/) and set the generated Docker context to "rootless" (more secure) or [enable Docker CLI for the non-root user account](https://docs.docker.com/install/linux/linux-postinstall/#manage-docker-as-a-non-root-user) (less secure) that will be used to run VS Code.

とあるので、[Post-installation steps for Linux - Docker Documentation](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)にしたがって

* [Dockerの非rootユーザの実行許可](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)
* [リモートアクセスの構成](https://docs.docker.com/config/daemon/remote-access/#configuring-remote-access-with-daemonjson)

を行います。

:::note warn
[記事執筆時点（2020/08/16）のREADME](https://github.com/microsoft/vscode-docker/blob/2c17f20f75dc5f33cf215c28cfe66aea804fe1d7/README.md#installation)ではRootlessモードを利用したDockerの構成方法がなく、記事の更新にあたって検証もできていないため非rootユーザーで実行する方法で説明しています。**これから対処される場合は以降に示す方法ではなく[Rootlessモードの利用](https://docs.docker.jp/engine/security/rootless.html)が推奨されます。**
:::

### Dockerの非rootユーザの実行許可
[ドキュメント](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)のとおりやるだけ。これにより`sudo`なしで`docker`コマンドの実行が可能になります。

1. `docker`グループの作成　`$ sudo groupadd docker`
2. ユーザを`docker`グループに追加　`$ sudo usermod -aG docker $USER`
3. グループへの変更を適用　`$ newgrp docker`
4. `sudo`なしでコマンドが実行できるか確認　`$ docker run hello-world`

### リモートアクセスの構成
WSLでは`systemd`は素直には利用できない[^wsl-systemd]ので`daemon.json`によりリモートアクセスを構成します。

[^wsl-systemd]: 最新のWSLではsystemdが公式にサポートされています。
[Systemd support is now available in WSL! - Windows Command Line](https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/)

1. `/etc/docker/daemon.json`ファイルを作成する。（`/etc/docker`ディレクトリは存在しないはずなので手動作成。）
2. 作成した`daemon.json`に下記を記述

    ```json:/etc/docker/daemon.json
    {
      "hosts": ["unix:///var/run/docker.sock", "tcp://127.0.0.1:2375"]
    }
    ```
3. Ubuntuを再起動
4. 動作確認

    ```bash
    $ sudo ss | grep docker
    u_str ESTAB 0      0                  /run/guest-services/docker.sock 367124                                * 330544
    u_str ESTAB 0      0                  /run/guest-services/docker.sock 367126                                * 330545
    u_str ESTAB 0      0                  /run/guest-services/docker.sock 307037                                * 309995
    u_str ESTAB 0      0                  /run/guest-services/docker.sock 305761                                * 316051
    u_str ESTAB 0      0                  /run/guest-services/docker.sock 305703                                * 386143
    u_str ESTAB 0      0                  /run/guest-services/docker.sock 305701                                * 386142
    ```

## トラブルシューティング
Ubuntuで何も設定していない状態なら、上記までの手順でDocker拡張機能から接続できるようになると思います。

ターミナルから`docker`コマンドを実行して、`Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?`エラーが表示される場合は[環境変数を削除](https://docs.docker.com/engine/install/linux-postinstall/#cannot-connect-to-the-docker-daemon)する必要があります。

* `~/.bashrc`や`~/.profile`などの該当箇所の削除
* VSCodeの設定の`docker.host`を削除

を行います。私の場合は`tcp://127.0.0.1:2375`を設定していましたが、これらを削除したことにより問題なくDockerの操作と拡張機能からの接続が行えるようになりました。

## 参考
* [[Docker / VSCode] VSCodeからリモートマシンのDocker情報にアクセスする](/siruku6/items/11a9196c395ba4797aec)