Linux

WSL2のUbuntu 20.04 / 20.10 でSystemdでDockerを起動させる

はじめに

WSL2のUbuntu 20.04 / 20.10 でSystemdでDockerを起動をしてみたいと思います。以前はUbuntu 22.04 で動作する方法を紹介しましたが、まだまだUbuntu 20.04ユーザーは多いので紹介していきます。

Ubuntu 22.04での利用方法は以下を参考にしてください。

WSL2のUbuntu 22.04でSystemdでDockerを起動させる - 技術的な何か。
WSL2のUbuntu 22.04でSystemdでDockerを起動させる - 技術的な何か。

はじめに これまでWSL2ではDocker を立ち上げるにはSystemdではなくserviceで立ち上げるのが定番でした。これはUbuntu 22.04以前ではSystemdがPID=1で立ち上がら

level69.net

Ubuntu 20.0ではwsl-systemd がありません。そこで下記のwsl2-hacksを使った方法を参考にします。

GitHub - shayne/wsl2-hacks: Useful snippets / tools for using WSL2 as a development environment
GitHub - shayne/wsl2-hacks: Useful snippets / tools for using WSL2 as a development environment

Useful snippets / tools for using WSL2 as a development environment - GitHub - shayne/wsl2-hacks: Us ...

github.com

これはMicrosoft Storeなどからインストールした場合の方法になるため、直接インポートした場合の方法を紹介していきます。

 

--2022/09/30 追記--

Windows のビルドのバージョンは22000.0以上の場合、Windows 11 やWindows 10 Insider ProgramなどではWSLがSystemdに対応したのでこちらをお試しください。

WSLでsystemdのPID=1に対応したらしいので試してみた - 技術的な何か。
WSLでsystemdのPID=1に対応したらしいので試してみた - 技術的な何か。

はじめに WSLでsystemdをPID=1に対応しました。非常にうれしいニュースです。 現状はWindows 11かWindows 10 Insider Programのみです。ビルドのバージョンは

level69.net

 

設定

事前にアップデートを行っておきます。

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
[Tips] WSLにおけるsudoのパスワード変更とNOPASSWDについて - 技術的な何か。
[Tips] WSLにおけるsudoのパスワード変更とNOPASSWDについて - 技術的な何か。

Tips WSL(Windows Store : Ubuntu 20.04 LTS)でのパスワードについてTipsです。 sudoを実行する場合のパスワード変更です。 sudoで求められるパスワードは

level69.net

/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をインストール

インストールは公式ドキュメント通りです。

Install Docker Engine on Ubuntu | Docker Documentation
Install Docker Engine on Ubuntu | Docker Documentation

Instructions for installing Docker Engine on Ubuntu

docs.docker.com

$ 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を活用したい人は導入してみてください。

-Linux
-