はじめに
WSL2のUbuntu 20.04 / 20.10 でSystemdでDockerを起動をしてみたいと思います。以前はUbuntu 22.04 で動作する方法を紹介しましたが、まだまだUbuntu 20.04ユーザーは多いので紹介していきます。
Ubuntu 22.04での利用方法は以下を参考にしてください。
Ubuntu 20.0ではwsl-systemd がありません。そこで下記のwsl2-hacksを使った方法を参考にします。
これはMicrosoft Storeなどからインストールした場合の方法になるため、直接インポートした場合の方法を紹介していきます。
--2022/09/30 追記--
Windows のビルドのバージョンは22000.0以上の場合、Windows 11 やWindows 10 Insider ProgramなどではWSLがSystemdに対応したのでこちらをお試しください。
設定
事前にアップデートを行っておきます。
apt update apt upgrade
インストール
次に以下のパッケージをインストールします。
apt install dbus policykit-1 daemonize
fakeのShellを作成する
ここら辺は仕組みとか気にせず設定していきます。知りたい人はgithubを参考にしてください。
touch /usr/local/bin/wsl2hack chmod +x /usr/local/bin/wsl2hack vi /usr/local/bin/wsl2hack
エディタはご自由に。
<YOURUSER>は今回の例ではubuserに変更しています。
#!/bin/bash
# your WSL2 username
#UNAME="<YOURUSER>"
UNAME="ubuser"
UUID=$(id -u "${UNAME}")
UGID=$(id -g "${UNAME}")
UHOME=$(getent passwd "${UNAME}" | cut -d: -f6)
USHELL=$(getent passwd "${UNAME}" | cut -d: -f7)
if [[ -p /dev/stdin || "${BASH_ARGC}" > 0 && "${BASH_ARGV[1]}" != "-c" ]]; then
USHELL=/bin/bash
fi
if [[ "${PWD}" = "/root" ]]; then
cd "${UHOME}"
fi
# get pid of systemd
SYSTEMD_PID=$(pgrep -xo systemd)
# if we're already in the systemd environment
if [[ "${SYSTEMD_PID}" -eq "1" ]]; then
exec "${USHELL}" "$@"
fi
if [[ -z ${SYSTEMD_PID} ]]; then
# start systemd
/usr/bin/daemonize -l "${HOME}/.systemd.lock" /usr/bin/unshare -fp --mount-proc /lib/systemd/systemd --system-unit=basic.target
# wait for systemd to start
retries=50
while [[ -z ${SYSTEMD_PID} && $retries -ge 0 ]]; do
(( retries-- ))
sleep .1
SYSTEMD_PID=$(pgrep -xo systemd)
done
if [[ $retries -lt 0 ]]; then
>&2 echo "Systemd timed out; aborting."
exit 1
fi
fi
# export WSL variables
export WINPATH="$(echo "$PATH"|grep -o ':/mnt/c.*$'|sed 's!^:!!')"
RUNOPTS=""
RUNOPTS="$RUNOPTS -l"
RUNOPTS="$RUNOPTS -w WINPATH"
RUNOPTS="$RUNOPTS -w WSL_INTEROP"
RUNOPTS="$RUNOPTS -w WSL_DISTRO_NAME"
# enter systemd namespace
exec /usr/bin/nsenter -t "${SYSTEMD_PID}" -m -p --wd="${PWD}" /sbin/runuser $RUNOPTS -s "${USHELL}" "${UNAME}" -- "${@}"
ここで一般ユーザー(例:ubuser)を作成します。起動時のユーザーになります。
adduser ubuser
作成したユーザがsudoを利用できるようにvisudoで下記を追加します。
ubuser ALL=(ALL) NOPASSWD: ALL
/etc/passwd にFakeのshellを設定します。
vipw
最初の行に以下を追加します。
rootwsl:x:0:0:root:/root:/usr/local/bin/wsl2hack
WSLの終了と起動
PoweshellでいったんWSLを終了します。
wsl --shutdown -d ディストリビューション名
再度、Windowsターミナルなどで起動します。
この時、ユーザーはubuserで起動されています。
確認
以下のコマンドで確認します。
systemctl is-active dbus
またps ax | grep systemdを確認すると
1 ? Ss 0:01 /lib/systemd/systemd --system-unit=basic.target
PID=1で起動されていることが確認できます。
Dockerをインストール
インストールは公式ドキュメント通りです。
$ systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-08-11 01:55:01 JST; 35min ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 1911 (dockerd)
Tasks: 14
Memory: 44.8M
CGroup: /system.slice/docker.service
└─1911 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ログインしているユーザーでdockerコマンドが利用できるようにします。
sudo usermod -aG docker ubuser
コマンドが利用できるか確認します。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
接続できています。
以上で設定は完了です。
まとめ
wsl2-hacksを利用したsystemdを紹介しました。あまり日本では紹介されていないので取り上げてみましたが、Ubuntu 20.04ユーザーにとっては便利なものです。Systemdを活用したい人は導入してみてください。


