hiroの長い冒険日記

主にコンピュータ周辺の興味を持った内容を綴ります

Windows11 WSL2 で systemd

Windows11 の WSL2 では systemd が動作しておらず、SystemV init とも異なるMicrosoft 独自の init が PID 1 で起動しています。Windows との連携や高速に仮想マシンを起動する為には必要な事なのかもしれませんが、現在の Linux distribution では systemd がほぼ標準で使用されている事もあり、daemon の起動・停止や各種サービスについての知識が活用できない事が多くあります。起動や処理速度が遅くなるのはある程度許容した上で、WSL2 で systemd を使えるようにしてみました。WSL2 で systemd を使用する方法には複数ありますので、それぞれについて試してみました。



2022.10.16 追記 Ubuntu 標準の systemd を使ってみました。

hiro20180901.hatenablog.com

WSL2 に複数の Ubuntu を install する

元々使用している WSL2 Ubuntu の環境は維持したいので、別の Ubuntu を WSL2 に install し、そちらで systemd を試してみました。

現在は Microsoft Store から「Ubuntu」アプリを install しており、実際には Ubuntu 20.04.4 LTS になっています。

Ubuntu bash :

$ cat /etc/os-release | grep PRETTY_NAME
PRETTY_NAME="Ubuntu 20.04.4 LTS"

WSL2 では、「Ubuntu」の他に「Ubuntu 20.04」も提供されており、この2つは別の環境として使用できます。

cmd.exe :

>wsl --list --online
NAME            FRIENDLY NAME
Ubuntu          Ubuntu
Debian          Debian GNU/Linux
kali-linux      Kali Linux Rolling
openSUSE-42     openSUSE Leap 42
SLES-12         SUSE Linux Enterprise Server v12
Ubuntu-16.04    Ubuntu 16.04 LTS
Ubuntu-18.04    Ubuntu 18.04 LTS
Ubuntu-20.04    Ubuntu 20.04 LTS

新しく install した「Ubuntu 20.04」を base に、もう2つの Ubuntu を準備しました。既にある環境を複製するには、export / import すれば可能です。
naonaorange.hatenablog.com

Ubuntu-20.04、Ub_2、Ub_3 の三つの Ubuntu を追加しました。Ub_2 と Ub_3 は、他の仮想マシンと同じ folder 以下に保管するようにしました。
cmd.exe :

>wsl --install --distribution Ubuntu-20.04
# user, password の設定、apt 更新まで済ます
>wsl --list --all --verbose
  NAME            STATE           VERSION
* Ubuntu          Running         2
  Ubuntu-20.04    Running         2
>cd \Users\hiro\Documents
>mkdir WSL2_VMs
>cd WSL2_VMs
>wsl --export Ubuntu-20.04 Ubuntu-20.04.tar
>mkdir Ub_2
>wsl --import Ub_2 Ub_2 Ubuntu-20.04.tar
>mkdir Ub_3
>wsl --import Ub_3 Ub_3 Ubuntu-20.04.tar

Windows Terminal を再起動すれば、追加した全ての Ubuntu を menu から起動できます。

Option を追加して、root ではなく user で login するように変更しました。

複数の WSL2 distribution を同時に起動すると IP Address が同一

なお、複数の WSL2 distribution を同時に起動する事は可能ですが、IP Address が同一になるのは仕様との事です。
hetarena.com

同時に起動して sshd が動作せず戸惑いました。

WSL2 で systemd を使う複数の方法

WSL2 で systemd を使う方法は複数あります。軽量コンテナ内部で systemd を PID 1 で動作させる、という意味では手段は同じだと思いますが、試して自分に合う方法を探したいと思います。

  1. genie
  2. distrod
  3. unshare と nsenter
  4. その他

WSL2 で systemd その1 : genie

最初に genie を使用してみました。以下のページを参考にしました。
snowsystem.net
qiita.com
github.com

genie は軽量 container の内部で systemd PID = 1 の環境を作る為の software です。

手順の詳細はリンク先を参照して頂くとして、以下では手順をトレースしながら引っ掛かりそうな箇所を追記しました。

dotnet-runtime-5.0 の install

deb package を落としてきて、直接 dpkg で install します。

$ wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
$ rm packages-microsoft-prod.deb

依存 package の install

genie の依存している package を予め install しておきます。

$ sudo apt install --no-install-recommends daemonize dbus gawk libc6 libstdc++6 policykit-1 systemd systemd-container

WSL2 Ubuntu-20.04 の初期の状態で既に install されている package もありますので、実際に install されるのは daemonize と systemd-container の二つです。Recommends で他の package が install されないように--no-install-recommends option を付けています。

wsl-translinux repository の追加と update

Ubuntu-20.04 以外の別の apt repository と GPG の公開鍵を追加します。

($ sudo apt install apt-transport-https) -> 不要
$ sudo wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg
$ sudo chmod a+r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg
$ sudo tee /etc/apt/sources.list.d/wsl-transdebian.list << EOF > /dev/null
deb https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
EOF
$ sudo apt update

上のリンク先の説明では apt-transport-https を install するように書かれていますが、apt-transport-https package の説明を読むと現在では不要ですので install する必要はありません。実際の package 内には document しかありません。

$ apt show apt-transport-https
Package: apt-transport-https
…略…
Description: transitional package for https support
 This is a dummy transitional package - https support has been moved into
 the apt package in 1.5. It can be safely removed.

cat command で /etc/apt/sources.list.d/wsl-transdebian.list を作成し deb line と deb-src line を追加する方法は permission denied で失敗しました。sudo ではなく root で実行すれば上手く行くらしいですが、上に記載した tee を使用する方法では成功しました。

最後に repository を読み込む為に update します (upgrade は不要です)。

systemd-genie の install

genie を install します。package 名は systemd-genie になります。

systemd-genie に依存して build-essential が install されてしまいますが、これは python3-pip の Recommends に入っている為です。この段階で build-essential が不要であれば、apt--no-install-recommends option を付ける事で回避できます。

$ sudo apt install --no-install-recommends systemd-genie

genie 起動 -> Error

初回起動時には必ず error が発生します。"!" 1個が1秒に対応し、240秒の待ち時間の後に error message が表示されます。systemd が動作していないと回避方法も実行できませんので、一度は動作させる必要があります。-s option は軽量 container を初期化した後で container 内で shell を起動する option です。

$ genie -s
genie: WARNING: systemd default target is default.target; targets other than multi-user.target may not work
genie: WARNING: if you wish to use a different target, this warning can be disabled in the config file
genie: WARNING: if you experience problems, please change the target to multi-user.target
Waiting for systemd....!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
genie: systemd did not enter running state (degraded) after 240 seconds
genie: this may be due to a problem with your systemd configuration
genie: information on problematic units is available at https://github.com/arkane-systems/genie/wiki/Systemd-units-known-to-be-problematic-under-WSL
genie: a list of failed units follows:

  UNIT                       LOAD   ACTIVE SUB    DESCRIPTION
● ssh.service                loaded failed failed OpenBSD Secure Shell server
● systemd-remount-fs.service loaded failed failed Remount Root and Kernel File Systems
● multipathd.socket          loaded failed failed multipathd control socket

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

3 loaded units listed.
genie: WARNING: systemd is in degraded state, issues may occur!

Error は出ていますが、この段階で systemd PID = 1 の軽量 container 内部に入っています。

Warning と Error が幾つか出ていますので、それぞれに対処します。

  1. default.target を multi-user.target に変更
  2. ssh.service 起動できず
  3. systemd-remount-fs.service 起動できず
  4. multipathd.socket 起動できず

対処方法については前記の link 先に記載があります。

初回起動時に 240 秒待ちたくない場合には、/etc/genie.ini を編集すれば短くすることが出来ます。systemd-timeout を 240 から 20 秒程度にすれば短くなります。
/etc/genie.ini

[genie]
systemd-timeout=240  # <- 20 に変更
clone-env=WSL_DISTRO_NAME,WSL_INTEROP,WSLENV,DISPLAY,WAYLAND_DISPLAY,PULSE_SERVER
secure-path=/lib/systemd:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
clone-path=false
target-warning=true
update-hostname=true
update-hostname-suffix=-wsl
resolved-stub=false

Warning と Error の回避方法

genie の軽量 container 内部の環境で実行します。

default.target を multi-user.target に変更

default は graphical.target になっていました。これを multi-user.target に変更します。

$ systemctl get-default
graphical.target
$ sudo systemctl set-default multi-user.target
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target.
$ systemctl get-default
multi-user.target

ssh.service

WSL2 install 後、sshd を一度でも起動していない場合には、systemd から ssh.service を起動しようとすると error が出ます。host 用の key を作成すれば起動できます。

$ sudo ssh-keygen -A

systemd-remount-fs.service

root filesystem の disklabel が cloudimg-rootfs である事が要求されていますが、実際には空白であるために発生するとの事です。root filesystem を調べて e2label で書き換えます。

$ df
Filesystem      1K-blocks      Used  Available Use% Mounted on
/dev/sdc        263174212   2282960  247453096   1% /
…以下略…
# root filesystem は /dev/sdc
# 確認 -> 空白
$sudo e2label /dev/sdc

$ sudo e2label /dev/sdc cloudimg-rootfs
# 確認
$ sudo e2label /dev/sdc
cloudimg-rootfs

multipathd.socket

multipathd.socket は WSL2 では使用できないので無効化します。

$ sudo systemctl disable multipathd.socket

genie 起動 -> 成功

Warning と Error の対処が済めば、genie は2~3秒程度で起動できます。genie 起動前後の process の状態を以下に示します。

$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0   1756  1020 ?        Sl   17:21   0:00 /init
root           7  0.0  0.0   1752    68 ?        Ss   17:21   0:00 /init
root           8  0.0  0.0   1752    76 ?        D    17:21   0:00 /init
hiro           9  0.0  0.0  10180  5240 pts/0    Ss   17:21   0:00 -bash
root         138  0.0  0.0   1756    80 ?        Ss   19:17   0:00 /init
root         139  0.0  0.0   1764    80 ?        S    19:17   0:00 /init
hiro         140  0.0  0.0  10048  5016 pts/1    Ss+  19:17   0:00 -bash
hiro        5966  0.0  0.0  10616  3304 pts/0    R+   19:47   0:00 ps aux
$ genie -s
Waiting for systemd....!
Ub_1:~:$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0 173772 13216 ?        Ss   16:05   0:00 systemd
root          39  0.0  0.0  51372 15608 ?        S<s  16:05   0:00 /lib/systemd/systemd-journald
root          58  0.0  0.0  19564  5048 ?        Ss   16:05   0:00 /lib/systemd/systemd-udevd
systemd+      65  0.0  0.0  18380  6644 ?        Ss   16:05   0:00 /lib/systemd/systemd-networkd
systemd+     249  0.0  0.0  23928 12552 ?        Ss   16:05   0:00 /lib/systemd/systemd-resolved
message+     267  0.0  0.0   7628  4700 ?        Ss   16:05   0:00 /usr/bin/dbus-daemon --system --address=systemd: --no
root         278  0.0  0.1  29196 17924 ?        Ss   16:05   0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-s
syslog       280  0.0  0.0 224348  4272 ?        Ssl  16:05   0:00 /usr/sbin/rsyslogd -n -iNONE
root         286  0.0  0.2 1907044 48332 ?       Ssl  16:05   0:00 /usr/lib/snapd/snapd
root         294  0.0  0.0  16656  7392 ?        Ss   16:05   0:00 /lib/systemd/systemd-logind
root         427  0.0  0.0   8540  3020 ?        Ss   16:05   0:00 /usr/sbin/cron -f
root         442  0.0  0.1 108116 20752 ?        Ssl  16:05   0:00 /usr/bin/python3 /usr/share/unattended-upgrades/unatt
daemon       448  0.0  0.0   3796  2264 ?        Ss   16:05   0:00 /usr/sbin/atd -f
root         472  0.0  0.0  12176  6860 ?        Ss   16:05   0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startu
root         482  0.0  0.0   7356  2320 tty1     Ss+  16:05   0:00 /sbin/agetty -o -p -- \u --noclear --keep-baud consol
root         517  0.0  0.0   5832  1824 ?        Ss   16:05   0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root         577  0.0  0.0   2612   600 pts/0    S+   16:05   0:00 /bin/sh -c machinectl shell -q hiro@.host
root         578  0.0  0.0  20996  5612 pts/0    D+   16:05   0:00 machinectl shell -q hiro@.host
root         579  0.0  0.0  16296  6184 ?        Ss   16:05   0:00 /lib/systemd/systemd-machined
hiro         580  0.0  0.0  10036  5156 pts/1    Ss   16:05   0:00 /bin/bash -l
hiro         585  0.0  0.0  18264  9552 ?        Ss   16:05   0:00 /lib/systemd/systemd --user
hiro         586  0.0  0.0 175136  3292 ?        S    16:05   0:00 (sd-pam)
hiro         597  0.0  0.0 175328  3360 pts/1    S    16:05   0:00 (sd-pam)
root        1020  0.0  0.1 283812 18028 ?        Ssl  16:06   0:00 /usr/lib/packagekit/packagekitd
root        1024  0.0  0.0 236420 11072 ?        Ssl  16:06   0:00 /usr/lib/policykit-1/polkitd --no-debug
hiro        1104  0.0  0.0  10616  3272 pts/1    R+   16:11   0:00 ps aux

genie を実行する前の WSL2 Ubuntu の状態では、Microsoft の init 以外は殆ど起動していない状態ですが、genie -s で軽量 container の内部に入ると systemd の multi-user.target を基準として様々な daemon が起動されます。とはいえ、prompt が出るまでは数秒ですので、それほど重い感じはありません。

元々、systemd は SystemV init の起動の遅さを解消するために、出来るだけ並列化して各種 daemon を起動させる事を目的として開発されているので、それほど起動には時間を要していないのだと思います。

genie 起動後には systemd が PID 1 で起動していますので、systemctl や journalctl も使えるようになります。

genie の終了方法

genie の軽量 container 内部の sh を終了すると、WSL2 の prompt に戻ります。ただ、この状態では genie によって起動された systemd 由来の daemon が起動したままになっています。

これらを一括して終了するには、以下の command を実行します。

$ genie --shutdown

他にも genie には様々な option がありますので、man page を参照ください。-b or --is-in-bottle は軽量 container 内部に居るかどうかの判別用です。

$ genie -b
inside
$ exit
logout
$ genie -b
outside

genie 導入結果

genie を導入・使用してみた感想は以下の通りです。

  • 導入手順は、これまでも改善されているのだと思いますが、煩雑だと思います。apt line 追加して update & install で済む状態ではありません。とはいえ、手順を整理すれば数分で終了しますし、幾度も実施する作業ではありませんので、私には許容範囲だと感じました。
  • Ubuntu-20.04 の環境では問題なく導入できましたが、依存している外部 package が多いので、Ubuntu の Version Up や各種 library の更新に伴って動作しなくなる心配があります。
  • install は手順を整理すれば時間を要しませんが、uninstall は大変そうです。debian 系だと apt での管理に慣れていますので、dotnet-runtime もapt line で管理できるようになれば改善されると感じました。
  • Windows11 の WSLg も問題なく動作しました。

WSL2 で systemd その2 : distrod

WSL2 で systemd を有効にする方法の二つ目は distrod という software です。
github.com
zenn.dev

distrod は二種類の方法で使用する事が出来ます。

  1. systemd が動作する container を linuxcontainers.org から新しく install する
  2. 既に install されている WSL2 distribution に install して systemd を有効にする

両方について試してみます。

systemd が動作する container を新しく install する方法

【追記】
こちらの方法では、/mnt/wslg 以下の一部の Owner が ubuntu になってしまう為、gnome-tweaks 等で設定を変更できませんでした。2番目の WSL Distribution に install する方法では問題なく使用できます。2番目の方法をお勧めします。
【追記おわり】

上記リンク先から install 用の zip file を download、展開し、Windows上から distrod_wsl_launcher.exe を実行する事で WSL2 に distribution を install します。WSL2 に含まれない distribution も install する事が出来ます。distrod_wsl_launcher.exe-d option を追加すると、distribution の 表示名を変更することが出来ます。
cmd.exe :

> distrod_wsl_launcher.exe -d Ubuntu_systemd

CUI base の installer ですので、cmd.exePowerShell から起動して数字で選択しながら進めます。
distrod_wsl_launcher 起動直後 :

tar.xz file 又は linuxcontainers.org のどちらから install するか選択します。linuxcontainers.org から install する場合には Default で良いので Enter を押します。

Distribution の選択 :

24種類の Distribution から選択します。Default の 23番の ubuntu を選択します。

選択肢に plamo もありましたので選んでみましたが、plamo linux は systemd 環境ではない事、及び package を install する command 等も入っていませんでしたので、使えるようにするにはもう少し作業が必要かと思います。こちらについては後で確認しようと考えています。

Ubuntu code name の選択 :

bionic (18.04 LTS)、impish (21.10)、focal (20.04 LTS)、xenial (16.04 LTS)、hirsute (21.04)、jammy (22.04 LTS) から選択します。Default の focal (20.04 LTS) を選択します。

username と password 入力 :

username と password を入力します。WSL2 に distribution を install した時と同様です。

distrod 起動直後 :

distrod の shell が起動した状態です。Windows Terminal を再起動すれば distrod 又は指定した名称の distribution が menu に追加されていて、wsl --list にも表示されます。

distrod で install した distribution は再起動しても systemd が有効の状態で起動します。必須ではありませんが、もし Windows が起動した直後から distribution を起動させたい場合には、以下を実行します。
distrod shell :

$ sudo /opt/distrod/bin/distrod enable --start-on-windows-boot

install 済みの WSL2 distribution で systemd を有効にする方法

genie と同じように、distrod でも install 済みの WSL2 distribution で systemd を有効にすることが出来ます。

install & 有効化

install 用の script を download し実行します。

WSL2 shell :

$ curl -L -O "https://raw.githubusercontent.com/nullpo-head/wsl-distrod/main/install.sh"
$ chmod +x install.sh
$ sudo ./install.sh install
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   152  100   152    0     0    603      0 --:--:-- --:--:-- --:--:--   600
100   657  100   657    0     0   1428      0 --:--:-- --:--:-- --:--:--  1428
100 11.6M  100 11.6M    0     0  8283k      0  0:00:01  0:00:01 --:--:-- 21.6M
alias/
bin/
bin/portproxy
bin/distrod-exec
bin/adduser
bin/portproxy.exe
bin/chsh
bin/distrod
bin/useradd
conf/
conf/tcp4_ports
conf/distrod.toml
ld/
ld/ld-linux-x86-64.so.2
lib/
lib/libm.so.6
lib/libpthread.so.0
lib/librt.so.1
lib/libssl.so.1.1
lib/libc.so.6
lib/libdl.so.2
lib/libcrypto.so.1.1
lib/libgcc_s.so.1
lib/liblzma.so.5
misc/
misc/licenses/
misc/licenses/libs/
misc/licenses/libs/libgcc-s1/
misc/licenses/libs/libgcc-s1/libgcc_s.so.1.LICENSE
misc/licenses/libs/libgcc-s1/copyright
misc/licenses/libs/liblzma5/
misc/licenses/libs/liblzma5/liblzma.so.5.LICENSE
misc/licenses/libs/liblzma5/copyright
misc/licenses/libs/libc6/
misc/licenses/libs/libc6/libdl.so.2.LICENSE
misc/licenses/libs/libc6/ld-linux-x86-64.so.2.LICENSE
misc/licenses/libs/libc6/libc.so.6.LICENSE
misc/licenses/libs/libc6/libm.so.6.LICENSE
misc/licenses/libs/libc6/libpthread.so.0.LICENSE
misc/licenses/libs/libc6/librt.so.1.LICENSE
misc/licenses/libs/libc6/copyright
misc/licenses/libs/libssl1.1/
misc/licenses/libs/libssl1.1/libcrypto.so.1.1.LICENSE
misc/licenses/libs/libssl1.1/libssl.so.1.1.LICENSE
misc/licenses/libs/libssl1.1/copyright
misc/licenses/crate-license.html
misc/distrod-post-update
run/
run/tmpfiles.d/
run/tmpfiles.d/x11.conf
run/systemd/
run/systemd/system/
run/systemd/system/portproxy.service
Installation is complete!

distrod を有効化します。
WSL2 shell :

$ sudo /opt/distrod/bin/distrod enable

一旦 WSL2 を終了して再起動すれば systemd 環境になります。systemd 無効 / 有効環境の比較です。

WSL2 shell : systemd 無効

$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   1744  1076 ?        Sl   20:50   0:00 /init
root         7  0.0  0.0   1752    64 ?        Ss   20:50   0:00 /init
root         8  0.0  0.0   1752    72 ?        R    20:50   0:00 /init
hiro         9  0.5  0.0  10048  4888 pts/0    Ss   20:50   0:00 -bash
hiro        24  0.0  0.0  10616  3260 pts/0    R+   20:50   0:00 ps aux

WSL2 shell : systemd 有効

$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.4  0.0 170324 12452 ?        Ss   20:48   0:00 /sbin/init systemd.setenv=WSL_DISTRO_NAME=Ub_2 system
hiro           3  0.0  0.0  10532  2800 pts/0    S    20:48   0:00 distrod-exec -- /bin/bash -bash
hiro           4  0.0  0.0  10048  5124 pts/0    S    20:48   0:00 -bash
root          61  0.1  0.0  36864 11648 ?        S<s  20:48   0:00 /lib/systemd/systemd-journald
root          76  0.0  0.0  21616  5188 ?        Ss   20:48   0:00 /lib/systemd/systemd-udevd
root          87  0.0  0.0   3644  1636 ?        Ss   20:48   0:00 snapfuse /var/lib/snapd/snaps/snapd_14549.snap /snap/
root          88  0.0  0.0   3820  1540 ?        Ss   20:48   0:00 snapfuse /var/lib/snapd/snaps/lxd_21835.snap /snap/lx
root          89  0.3  0.0   3872  1692 ?        Ss   20:48   0:00 snapfuse /var/lib/snapd/snaps/core20_1328.snap /snap/
root         137  0.0  0.0   8540  2856 ?        Ss   20:48   0:00 /usr/sbin/cron -f
message+     144  0.0  0.0   7372  4080 ?        Ss   20:48   0:00 /usr/bin/dbus-daemon --system --address=systemd: --no
root         161  0.0  0.1  29216 17868 ?        Ss   20:48   0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-s
syslog       162  0.0  0.0 224348  6880 ?        Ssl  20:48   0:00 /usr/sbin/rsyslogd -n -iNONE
root         172  0.8  0.3 2350204 52800 ?       Ssl  20:48   0:00 /usr/lib/snapd/snapd
root         183  0.0  0.0  16444  6276 ?        Ss   20:48   0:00 /lib/systemd/systemd-logind
daemon       185  0.0  0.0   3796  2212 ?        Ss   20:48   0:00 /usr/sbin/atd -f
root         309  0.0  0.1 108108 20684 ?        Ssl  20:48   0:00 /usr/bin/python3 /usr/share/unattended-upgrades/unatt
hiro         937  0.0  0.0  10616  3244 pts/0    R+   20:49   0:00 ps aux

distrod の uninstall

distrod を uninstall するには、無効化して install 用の script で uninstall を実行します。

distrod : 無効

$ sudo /opt/distrod/bin/distrod disable

cmd.exe : shutdown

> wsl --shutdown

distrod : uninstall

$ sudo ./install.sh uninstall

distrod 導入結果

distrod を導入・使用してみた感想は以下の通りです。

  • linux container を install する場合も WSL2 distribution に install する場合も、どちらも導入方法は簡単で分かりやすいと感じました。
  • library も /opt 以下を参照するようになっているので、元の distribution の影響を受けずに distrod のみで動作するようになっています。
  • 特に linux container を install する方法では、WSL2 には無い distribution も install する事が出来ますので、arch や gentoo を WSL2 で使う際には便利かと思います。(systemd を使用していない distribution の場合にはあまり意味がないかもしれませんが)
  • 起動して直ぐに systemd の環境になっているのはわかりやすいと感じました。(genie でも設定すれば可能ですが、default になっているのが使いやすい)
  • WSLg の起動も問題ありませんでした。
  • github で source を覗いてみたら Rust なんですね。勉強しないと。

WSL2 で systemd その3 : unshare と nsenter を使用する方法

util-linux の unshare と nsenter の機能でも軽量 container 内で systemd を起動させる事が可能です。
qiita.com

元のアイデアは、WSL2 上の Ubuntu で snap を使用するために systemd を起動する必要があり、その為の hack という形で公開されていました。
discourse.ubuntu.com

どちらかといえば、unshare と nsenter で実現していた機能を使いやすくしているのが genie / distrod なのでしょう。

unshare で軽量 container を作成して systemd を起動し、nsenter で作成した軽量 container の内部に入ります。daemonize が必要ですので install しておきます。

WSL2 Ubuntu :

$ sudo apt install daemonize  (初回のみ)
$ sudo daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=multi-user.target 
$ exec sudo nsenter --target $(pidof systemd) --all su - $LOGNAME

これで multi-user.target を基準として systemd が起動している軽量 container 内の shell に入ることが出来ます。

使い勝手としては、

  • genie や distrod と同様の systemd unit の問題は発生しましたが、同じ対処方法で解決できました。
  • WSLg はそのままでは使えませんでした。環境変数かなと思いますが、genie や distrod で WSLg を使える状況なので、追いかけるのは止めました。

$ gedit
Unable to init server: Could not connect: Connection refused
(gedit:608): Gtk-WARNING **: 23:02:12.063: cannot open display:

  • 標準で Ubuntu に入っている util-linux の unshare と nsenter (+ daemonize ) で軽量 container 内の systemd 環境を構築できるのはメリットです。WSLg が必要ない場合には、command 二つで systemd 環境になります。

WSL2 で systemd その他

これ以降は、見つけましたが試していないものです。

subsystemctl

genie に触発されて作成されたものとの事ですが、Arch Linux を WSL2 で使用するために使用されている事が多いようです。
GitHub - sorah/subsystemctl: Utility to run systemd in WSL2 with a Linux namespace

link 先に記載がありますが、

Maintanence Note: You may want to use nullpo-head/wsl-distrod which provides better compatibility with systemd and easier installation, and well maintained.

distrod の方がお勧めとの事です。

script base のもの

WSL2のUbuntuでsystemdとsnapdとLXDとdockerを動かしてみた · hnakamur's blog

GitHub - diddledani/one-script-wsl2-systemd: The one-script variant of the systemd hack for WSL2
一つ目には unshare と nsenter の組み合わせで WSLg に対応する為の設定があります。

まとめ

Windows11 の WSL2 で systemd を使う方法3種類 (genie, distrod, unshare & nsenter) を試してみました。ググると genie の記事が多いのですが、個人的には distrod の使い勝手が良いと感じました。不要な際の uninstall script も用意されているのが好印象です。先ずは distrod を使用して色々と作業してみたいと考えています。

軽量 container 内部では systemd が動作していますので、先日試した qemu-kvm の permission も正常に反映されています。実機や仮想マシンの systemd の経験がそのまま生かせる (bad know-how が生じない) のは利点だと思います。

できれば WSL2 の標準として Microsoft init の代わりに systemd が起動できるのが一番良いですが実現するかどうかは分かりません。暫くの間は、この方法を代替として使用してみます。