Windows 11のWSL2（Ubuntu 22.04）：dockerコンテナ内で外部通信できるようにresolv.conf修正

# 1. はじめに

## 1.1. 動機

- [Windows 11のWSL2（Ubuntu 22.04）：systemd + docker環境構築 ](https://qiita.com/tomoten/items/22b451958d29f044168f)のdocker設定の続きです。
- WSL2は、起動時に/etc/resolv.confが自動生成され、自身のwindowsをnameserver指定します。
- この状態だと、WSL2のUbuntuでdockerコンテナを起動しても外部通信できないため、非常に不便です。
- 本記事では、WSL2のUbuntuの/etc/resolv.confについての修正設定を示します。

## 1.2. 環境

- WSL2ディストリビューション: Ubunbu 22.04
- docker はインストール＆起動確認済み
- wsl-systemd設定済み、windows terminal でUbuntuを起動すると、PID=1でsystemdが起動する

## 1.3. 参考資料

| No. | URL | 説明 |
| :-- | :-- | :-- |
| [1] | [WSL2 で dns の名前解決ができなくなって ネット接続できなくなった場合の対処方法](https://qiita.com/kkato233/items/1fc71bde5a6d94f1b982) | WSL2のresolv.confの仕様についてこちらを参照 |
| [2] | [systemd のユニットファイルの作り方](https://tex2e.github.io/blog/linux/create-my-systemd-service) | systemdのunitファイルの作り方についてはこちらを参照 |

# 2. 事象

- WSL2のUbuntuを起動すると、resolv.confは以下のようにシンボリックリンクが作成される。
- nameserverには、windowsのWSL用IPアドレスが設定されています。

```bash
$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 20 Jul 16 15:56 /etc/resolv.conf -> /mnt/wsl/resolv.conf

$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver WindowsのWSL用IPアドレス
```

- この状態で、コンテナubuntu:20.04を起動し、apt updateを実行しても外部通信することができない。

```bash
$ docker container run -it ubuntu:20.04
root@8715ec240240:/# apt update
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:2 http://security.ubuntu.com/ubuntu focal-security InRelease
  Temporary failure resolving 'security.ubuntu.com'
Err:3 http://archive.ubuntu.com/ubuntu focal-updates InRelease
  Temporary failure resolving 'archive.ubuntu.com'
(以下略)
```

# 3. resolv.confの修正

## 3.1. 方針

- 参考資料[[1]](https://qiita.com/kkato233/items/1fc71bde5a6d94f1b982)のように、/etc/wsl.confに`generateResolvConf = false`を設定します。
    - ただし、この場合、起動のたびに/etc/resolv.confが無い状態となります。
- そのため、systemdのサービスでresolv.confを作成するoneshotサービスを作成し、起動時に設定されるようにします。
    - unitファイルは、参考資料[[2](https://tex2e.github.io/blog/linux/create-my-systemd-service)]を参考にしています。

## 3.2. 設定

### wsl.conf

```config
[boot]
command = "/usr/libexec/wsl-systemd"

[network]
generateResolvConf = false
```

### systemdの起動時設定サービス

#### サービス定義ファイル：my-settings.service

- /etc/systemd/system/my-settings.serviceを以下のように作成します。

```config
[Unit]
Description=Making my settings

[Service]
Type=oneshot
ExecStart=/bin/bash /usr/local/bin/my-settings.sh

[Install]
WantedBy=multi-user.target
```

#### Exec処理：my-settings.sh

```bash
#!/bin/sh

# resolv.confの設定
echo "nameserver DNSのIPアドレス" >/etc/resolv.conf
```

#### 設定

- 以下のコマンドで、serviceを起動時有効にします。

```bash
$ sudo systemctl enable my-settings.service
Created symlink /etc/systemd/system/multi-user.target.wants/my-settings.service → /etc/systemd/system/my-settings.service.
```

# 4. 動作確認

- PowerShellにて`wsl --shutdown`からWSL2を一度止め、再度Ubuntuを起動します。
    - このとき、/etc/resolv.confが生成されていればOKです。
- この状態で、コンテナubuntu:20.04を起動し、apt updateを実行すると、外部通信できることが確認できます。

```bash
$ docker container run -it ubuntu:20.04
root@8715ec240240:/# apt update
Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
Get:2 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
Get:3 http://security.ubuntu.com/ubuntu focal-security/restricted amd64 Packages [1398 kB]
（中略）
Fetched 23.0 MB in 5s (4639 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
8 packages can be upgraded. Run 'apt list --upgradable' to see them.
```

# 5. おわりに

- 素のLinuxをずっと使っている身からすると、WSL2はかなりクセがありますね。。。