👻

WSL2 Ubuntu で PID1 を sytemd にする

2022/07/25に公開
2

Windows 11 にアップグレードして WSL2 で Ubuntu を試そうとしたところ systemctl が利用出来なかったので、その解決手順を本稿に記載しておきます。

序言

WSL2 に Ubuntu をインストールし systemctl コマンドを実行すると・・・

systemctl
> System has not been booted with systemd as init system (PID 1). Can't operate.
> Failed to connect to bus: Host is down

このままでは、サービスの自動起動や内部で systemctl を利用しているパッケージが動作しません。

プロセスを見てみると、PID 1 はinitとなっており、systemctl にはなっていません。
sytemctl は、PID 1 として全てのプロセスの親として振る舞うようにしないと動作しないようです。

ps -aux | head -n 2
> USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
> root         1  0.0  0.0   1744  1084 ?        Sl   11:23   0:00 /init

GitHub で公開されている Genie を利用することで systemd を PID1 で動作させることができるようです。内容は頻繁に更新されているようなので、手順に変更がないか事前に確認してください。
https://github.com/arkane-systems/genie

それでは設定していきましょう。

実行環境

  • Windows バージョン
エディション	Windows 11 Home
バージョン	21H2
インストール日	‎2022/‎07/‎24
OS ビルド	22000.832
エクスペリエンス	Windows 機能エクスペリエンス パック 1000.22000.832.0
  • Ubuntu バージョン
cat /etc/os-release
> NAME="Ubuntu"
> VERSION="20.04.4 LTS (Focal Fossa)"
> ...

解決手順

ここでは、WSL2 に Ubuntu をインストールした直後のため、事前にパッケージをアップデートしておきます。

sudo apt -y update
sudo apt -y dist-upgrade
依存パッケージのインストール

以前は dotnet-runtime-5.0 も必要だったようですが、現在は不要なようです。

sudo apt install -y daemonize dbus gawk libc6 policykit-1 python3 python3-pip python3-psutil systemd systemd-container
# パッケージの最新版取得、更新
sudo apt update
sudo apt dist-upgrade
依存パッケージ README抜粋 (at 25, Jul 2022)

Debian
Dependent packages on Debian are daemonize, dbus, gawk, libc6 (>= 2.2.5), policykit-1, python3 (>= 3.7), python3-pip, python3-psutil, systemd (>= 232-25), and systemd-container (>= 232-25). These should all be in the distro and able to be installed automatically.

wsl-transdebian のリポジトリ設定

下記を参考に wsl-transdebian のリポジトリ設定を行います。
https://arkane-systems.github.io/wsl-transdebian/

sudo su # superuserになる
apt install lsb-release
wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg
chmod a+r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg
cat << EOF > /etc/apt/sources.list.d/wsl-transdebian.list
> 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
apt update # リポジトリ情報を更新
exit # userに戻る
system-genie をインストール
sudo apt install -y systemd-genie
Genie の設定を行う
sudo cp /etc/genie.ini /etc/genie.ini.bak  # 設定ファイルをバックアップ
sudo sed -i 's/systemd-timeout=240/systemd-timeout=30/g' /etc/genie.ini  # タイムアウトを30秒に設定
sudo sed -i 's/update-hostname=true/update-hostname=false/g' /etc/genie.ini # ホスト表示に-wslが追加されないように設定
sudo ssh-keygen -A # sshdエラー回避の設定
PID 1 を systemd にする
genie -s # Genie を起動

初回起動時はWSLで対応していないサービスに関する警告メッセージが表示されますが、問題ありません。

root@PCName:~$ 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 30 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
● 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.

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

PID 1 が systemd になっているか確認します。

$ ps -aux | head -n 2
> USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
> root           1  1.3  0.3 175776 13204 ?        Ss   11:37   0:01 systemd
sytemd のdefault.target を変更

sytemd のデフォルトターゲットを変更します。

systemctl get-default
> graphical.target
sudo systemctl set-default multi-user.target
> Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target.
sudo systemctl list-dependencies
systemd-remount-fs.serviceのエラーを解消する

下記を参考にsystemd-remount-fs.serviceのエラーを解消します。
https://github.com/arkane-systems/genie/wiki/Systemd-units-known-to-be-problematic-under-WSL#systemd-remount-fsservice

ルートパーティションにラベル cloudimg-rootfs がないのが原因のようです。

cat /etc/fstab
> LABEL=cloudimg-rootfs   /        ext4   defaults        0 0

ルートパーティションのデバイスを確認します。

mount | grep '\s/\s'
> /dev/sdc on / type ext4 (rw,relatime,discard,errors=remount-ro,data=ordered)

df コマンドでも確認できます。

df
> Filesystem     1K-blocks      Used Available Use% Mounted on
> /dev/sdc       263174212   1789084 247946972   1% /

Mounted on/ になっている項目がルートパーティションです。

ルートパーティションにラベルを付与します。

sudo e2label /dev/sdc cloudimg-rootfs
その他対応していないサービスを無効化する
sudo systemctl disable getty@tty1
> Removed /etc/systemd/system/getty.target.wants/getty@tty1.service.
sudo systemctl disable multipathd.socket # WSL自体が非対応
> Removed /etc/systemd/system/sockets.target.wants/multipathd.socket.
systemctl が実行できるか確認
systemctl status sshd
> ● ssh.service - OpenBSD Secure Shell server
>      Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
>      Active: active (running) since Mon 2022-07-25 11:59:40 JST; 10s ago
WSL 起動時に Genie を実行するようにする

.bashrc の確認

ls -la ~/
> -rw-r--r-- 1 fehde fehde 3771 Jul 25 11:23 .bashrc

.bashrc を編集

cat << _EOF_ >> ~/.bashrc
>
> # Are we in the bottle?
> if [[ ! -v INSIDE_GENIE ]]; then
>   read -t 3 -p "yn? * Preparing to enter genie bottle (in 3s); abort? " yn
>   echo
>
>   if [[ \$yn != "y" ]]; then
>     echo "Starting genie:"
>     exec /usr/bin/genie -s
>   fi
> fi
> _EOF_

参考

https://shikiyura.com/2021/07/run_systemd_as_pid_1_on_wsl2_202107/
https://qiita.com/fjij/items/95e283ed2bff47a1a27c

Discussion

KensukeKensuke

現在では、PowerShellでwslを最新バージョンにし、再起動するとsystemctlが使えるようです。

> wsl --update
> wsl --shutdown
FehdeFehde

せっかくコメント頂いたのに見逃しておりました。
ご指摘ありがとうございます!追記させていただきます!