ノートパソコン買ったからWSL2の設定するよ

WSL2のインストール

wsl のインストールコマンドを打つ前に PowerShell 5.1 から PowerShell 7 にアップデートする。(ノリ)
$PSVersionTable
Name Value
---- -----
PSVersion 5.1.22621.963
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.22621.963
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

$ winget search Microsoft.PowerShell
'msstore' ソースを使用するには、使用する前に次の契約を表示する必要があります。
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
ソースが正常に機能するには、現在のマシンの 2 文字の地理的リージョンをバックエンド サービスに送信する必要があります (例: "US")。
すべてのソース契約条件に同意しますか?
[Y] はい [N] いいえ: y
名前 ID バージョン ソース
----------------------------------------------------------
PowerShell Microsoft.PowerShell 7.3.3.0 winget
PowerShell Microsoft.PowerShell.Preview 7.4.1.0 winget

管理者権限で実行する。
$ wsl --install
インストール中: Linux 用 Windows サブシステム
Linux 用 Windows サブシステム はインストールされました。
インストール中: Ubuntu
Ubuntu はインストールされました。
要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。

以降はMicrosoftが提供しているベストプラクティスに沿って行う。

スタートメニューからUbuntu を起動する。
ユーザー名 と パスワード を新規設定する。
ガイドにもあるようにWindows ユーザー名とは関係ないのでなんでもいい。

Ubuntuのパッケージの更新
sudo apt update && sudo apt upgrade

コードエディタとして VSCode をダウンロードする

WSLに Docker Engine をインストールする。
WindowsにDockerをインストールする必要が現状ないので、Docker Desktopは使わない選択をしています。

今回はDocker Engineインストール用の簡易スクリプトがDockerから提供されているのでそれを使う。
※本番環境では推奨されません。開発環境およびテスト環境でのみ推奨されます。

Docker Desktop をインストールしたほうがいいよ~と言われる。(Dockerからしたらそうでしょうね)
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
# Executing docker install script, commit: 66474034547a96caa0a25be56051ff8b726a1b28
WSL DETECTED: We recommend using Docker Desktop for Windows.
Please get Docker Desktop from https://www.docker.com/products/docker-desktop
You may press Ctrl+C now to abort this script.
+ sleep 20
+ sh -c apt-get update -qq >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null
+ sh -c mkdir -p /etc/apt/keyrings && chmod -R 0755 /etc/apt/keyrings
+ sh -c curl -fsSL "https://download.docker.com/linux/ubuntu/gpg" | gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg
+ sh -c chmod a+r /etc/apt/keyrings/docker.gpg
+ sh -c echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable" > /etc/apt/sources.list.d/docker.list
+ sh -c apt-get update -qq >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-scan-plugin docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin >/dev/null
================================================================================
To run Docker as a non-privileged user, consider setting up the
Docker daemon in rootless mode for your user:
dockerd-rootless-setuptool.sh install
Visit https://docs.docker.com/go/rootless/ to learn about rootless mode.
To run the Docker daemon as a fully privileged service, but granting non-root
users access, refer to https://docs.docker.com/go/daemon-access/
WARNING: Access to the remote API on a privileged Docker daemon is equivalent
to root access on the host. Refer to the 'Docker daemon attack surface'
documentation for details: https://docs.docker.com/go/attack-surface/
================================================================================

ドキュメント通りにコマンドを実行する。
$ dockerd-rootless-setuptool.sh install
[ERROR] Missing system requirements. Run the following commands to
[ERROR] install the requirements and run this tool again.
[ERROR] Alternatively iptables checks can be disabled with --skip-iptables .
########## BEGIN ##########
sudo sh -eux <<EOF
# Install newuidmap & newgidmap binaries
apt-get install -y uidmap
# Load ip_tables module
modprobe ip_tables
EOF
########## END ##########
足りないパッケージがあるのでいわれたとおりにコマンドを実行する。

$ sudo sh -eux <<EOF
# Install newuidmap & newgidmap binaries
apt-get install -y uidmap
# Load ip_tables module
modprobe ip_tables
EOF
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
uidmap
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 22.4 kB of archives.
After this operation, 147 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 uidmap amd64 1:4.8.1-2ubuntu2.1 [22.4 kB]
Fetched 22.4 kB in 1s (17.1 kB/s)
Selecting previously unselected package uidmap.
(Reading database ... 24411 files and directories currently installed.)
Preparing to unpack .../uidmap_1%3a4.8.1-2ubuntu2.1_amd64.deb ...
Unpacking uidmap (1:4.8.1-2ubuntu2.1) ...
Setting up uidmap (1:4.8.1-2ubuntu2.1) ...
Processing triggers for man-db (2.10.2-1) ...
+ modprobe ip_tables
modprobe: FATAL: Module ip_tables not found in directory /lib/modules/5.15.90.1-microsoft-standard-WSL2
失敗する。

$ modprobe ip_tables
modprobe: FATAL: Module ip_tables not found in directory /lib/modules/5.15.90.1-microsoft-standard-WSL2
↑この解消はカーネルの問題などで深そうだったのでいったん無視。
メッセージに提示されているように --skip-iptables
オプションを付与する。
$ dockerd-rootless-setuptool.sh install --skip-iptables
[INFO] systemd not detected, dockerd-rootless.sh needs to be started manually:
PATH=/usr/bin:/sbin:/usr/sbin:$PATH dockerd-rootless.sh --iptables=false
[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Use CLI context "rootless"
Current context is now "rootless"
[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):
export PATH=/usr/bin:$PATH
Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///mnt/wslg/runtime-dir/docker.sock

言われたとおりに .bashrc
にパスを通すことを追記する。
$ nano ~/.bashrc
# ~末尾まで省略~
# rootless docker settings
# Reference: https://docs.docker.com/engine/security/rootless/
export PATH=/usr/bin:$PATH
export DOCKER_HOST=unix:///mnt/wslg/runtime-dir/docker.sock

$ PATH=/usr/bin:/sbin:/usr/sbin:$PATH dockerd-rootless.sh --iptables=false
上記コマンドを打つことによってrootless dockerの起動はできるようになった。
でも毎回打つのは面倒だよね。

よく読んだら systemd の利用を激しく推奨していたので WSLで systemdを利用する設定をする。
Ubuntuの /etc/wsl.conf
に 設定を追記する。
sudo nano /etc/wsl.conf
[boot]
systemd=true
Ubuntuを再起動する。
wsl.exe --shutdown
Ubuntu側で systemd が有効かをチェックする。
systemctl list-unit-files --type=service
エラーが出てなければOK

systemd を有効にしてから改めてrootless docker のインストール
$ dockerd-rootless-setuptool.sh install --skip-iptables
[INFO] Creating /home/ubuntu/.config/systemd/user/docker.service
[INFO] starting systemd service docker.service
+ systemctl --user start docker.service
+ sleep 3
+ systemctl --user --no-pager --full status docker.service
● docker.service - Docker Application Container Engine (Rootless)
Loaded: loaded (/home/ubuntu/.config/systemd/user/docker.service; disabled; vendor preset: enabled)
Active: active (running) since Sun 2023-03-12 20:54:51 JST; 3s ago
Docs: https://docs.docker.com/go/rootless/
Main PID: 2264 (rootlesskit)
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/docker.service
├─2264 rootlesskit --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh --iptables=false
├─2275 /proc/self/exe --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh --iptables=false
├─2294 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 2275 tap0
├─2301 dockerd --iptables=false
└─2324 containerd --config /run/user/1000/docker/containerd/containerd.toml --log-level info
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.739026697+09:00" level=info msg="Loading containers: start."
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.767059122+09:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address"
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.775883367+09:00" level=info msg="Loading containers: done."
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.830460333+09:00" level=warning msg="Not using native diff for overlay2, this may cause degraded performance for building images: running in a user namespace" storage-driver=overlay2
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.830762107+09:00" level=warning msg="WARNING: Running in rootless-mode without cgroups. To enable cgroups in rootless-mode, you need to boot the system in cgroup v2 mode."
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.830794498+09:00" level=info msg="Docker daemon" commit=bc3805a graphdriver=overlay2 version=23.0.1
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.830872216+09:00" level=info msg="Daemon has completed initialization"
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.857314585+09:00" level=info msg="[core] [Server #10] Server created" module=grpc
Mar 12 20:54:51 Daichang-Laptop systemd[486]: Started Docker Application Container Engine (Rootless).
Mar 12 20:54:51 Daichang-Laptop dockerd-rootless.sh[2301]: time="2023-03-12T20:54:51.864472136+09:00" level=info msg="API listen on /run/user/1000/docker.sock"
+ DOCKER_HOST=unix:///run/user/1000//docker.sock /usr/bin/docker version
Client: Docker Engine - Community
Version: 23.0.1
API version: 1.42
Go version: go1.19.5
Git commit: a5ee5b1
Built: Thu Feb 9 19:47:01 2023
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 23.0.1
API version: 1.42 (minimum version 1.12)
Go version: go1.19.5
Git commit: bc3805a
Built: Thu Feb 9 19:47:01 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.18
GitCommit: 2456e983eb9e37e47538f59ea18f2043c9a73640
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
rootlesskit:
Version: 1.1.0
ApiVersion: 1.1.1
NetworkDriver: slirp4netns
PortDriver: builtin
StateDir: /tmp/rootlesskit1582161430
slirp4netns:
Version: 1.0.1
GitCommit: 6a7b16babc95b6a3056b33fb45b74a6f62262dd4
+ systemctl --user enable docker.service
Created symlink /home/ubuntu/.config/systemd/user/default.target.wants/docker.service → /home/ubuntu/.config/systemd/user/docker.service.
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger ubuntu`
[INFO] CLI context "rootless" already exists
[INFO] Use CLI context "rootless"
Current context is now "rootless"
Warning: DOCKER_HOST environment variable overrides the active context. To use "rootless", either set the global --context flag, or unset DOCKER_HOST environment variable.
[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):
export PATH=/usr/bin:$PATH
Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1000//docker.sock

$ systemctl --user start docker
特に何も言われない。
$ docker -v
Docker version 23.0.1, build a5ee5b1
dockerコマンドが非rootユーザーでも実行できるようになった。

やり直し
$ dockerd-rootless-setuptool.sh install --skip-iptables
[INFO] Creating /home/ubuntu/.config/systemd/user/docker.service
[INFO] starting systemd service docker.service
+ systemctl --user start docker.service
+ sleep 3
+ systemctl --user --no-pager --full status docker.service
● docker.service - Docker Application Container Engine (Rootless)
Loaded: loaded (/home/ubuntu/.config/systemd/user/docker.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2023-03-13 21:25:19 JST; 3s ago
Docs: https://docs.docker.com/go/rootless/
Main PID: 719 (rootlesskit)
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/docker.service
├─719 rootlesskit --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh --iptables=false
├─730 /proc/self/exe --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh --iptables=false
├─748 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 730 tap0
├─755 dockerd --iptables=false
└─775 containerd --config /run/user/1000/docker/containerd/containerd.toml --log-level info
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.234136628+09:00" level=info msg="Loading containers: start."
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.263123518+09:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address"
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.278140052+09:00" level=info msg="Loading containers: done."
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.286200218+09:00" level=warning msg="Not using native diff for overlay2, this may cause degraded performance for building images: running in a user namespace" storage-driver=overlay2
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.286392354+09:00" level=warning msg="WARNING: Running in rootless-mode without cgroups. To enable cgroups in rootless-mode, you need to boot the system in cgroup v2 mode."
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.286418032+09:00" level=info msg="Docker daemon" commit=bc3805a graphdriver=overlay2 version=23.0.1
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.286988849+09:00" level=info msg="Daemon has completed initialization"
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.323286939+09:00" level=info msg="[core] [Server #10] Server created" module=grpc
Mar 13 21:25:19 Daichang-Laptop systemd[577]: Started Docker Application Container Engine (Rootless).
Mar 13 21:25:19 Daichang-Laptop dockerd-rootless.sh[755]: time="2023-03-13T21:25:19.327800486+09:00" level=info msg="API listen on /run/user/1000/docker.sock"
+ DOCKER_HOST=unix:///run/user/1000//docker.sock /usr/bin/docker version
Client: Docker Engine - Community
Version: 23.0.1
API version: 1.42
Go version: go1.19.5
Git commit: a5ee5b1
Built: Thu Feb 9 19:47:01 2023
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 23.0.1
API version: 1.42 (minimum version 1.12)
Go version: go1.19.5
Git commit: bc3805a
Built: Thu Feb 9 19:47:01 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.18
GitCommit: 2456e983eb9e37e47538f59ea18f2043c9a73640
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
rootlesskit:
Version: 1.1.0
ApiVersion: 1.1.1
NetworkDriver: slirp4netns
PortDriver: builtin
StateDir: /tmp/rootlesskit3862740882
slirp4netns:
Version: 1.0.1
GitCommit: 6a7b16babc95b6a3056b33fb45b74a6f62262dd4
+ systemctl --user enable docker.service
Created symlink /home/ubuntu/.config/systemd/user/default.target.wants/docker.service → /home/ubuntu/.config/systemd/user/docker.service.
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger ubuntu`
[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Use CLI context "rootless"
Current context is now "rootless"
[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):
export PATH=/usr/bin:$PATH
Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1000//docker.sock

iptablesの問題解決をしないといけないかもしれない。
$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
update-alternatives: using /usr/sbin/iptables-legacy to provide /usr/sbin/iptables (iptables) in manual mode
$ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
update-alternatives: using /usr/sbin/ip6tables-legacy to provide /usr/sbin/ip6tables (ip6tables) in manual mode
$ sudo update-alternatives --config iptables
There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).
Selection Path Priority Status
------------------------------------------------------------
0 /usr/sbin/iptables-nft 20 auto mode
* 1 /usr/sbin/iptables-legacy 10 manual mode
2 /usr/sbin/iptables-nft 20 manual mode
Press <enter> to keep the current choice[*], or type selection number: 1

$ systemctl --user enable docker
$ sudo loginctl enable-linger $(whoami)
これやっちゃダメ……?
wsl2の場合は、/etc/wsl.conf
でsystemdをユーザー権限で動かせるようにしているので不要な気がする。

WSL2にRootLess Dockerをインストールするまとめ
- WSL2でsystemdを有効化させる。
- Ubuntu に docker ce をインストールする。
- RootLess Dockerのインストールをする。

dockerコンテナでイメージをpullするときに名前解決で失敗するので、その対策をする。

トラブルシューティング

New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow
Name : {7d0ccf33-6706-4b8d-96eb-fd05555c1587}
DisplayName : WSL
Description :
DisplayGroup :
Group :
Enabled : True
Profile : Any
Platform : {}
Direction : Inbound
Action : Allow
EdgeTraversalPolicy : Block
LooseSourceMapping : False
LocalOnlyMapping : False
Owner :
PrimaryStatus : OK
Status : 規則は、ストアから正常に解析されました。 (65536)
EnforcementStatus : NotApplicable
PolicyStoreSource : PersistentStore
PolicyStoreSourceType : Local
RemoteDynamicKeywordAddresses : {}

$ modprobe ip_tables
modprobe: FATAL: Module ip_tables not found in directory /lib/modules/5.15.90.1-microsoft-standard-WSL2
ここが失敗する限りはrootless docker は厳しそうだな~

ちなみにDockerグループにユーザーを入れることの懸念点