WSLでsystemctlが使えない|PID 1とsystemdの状態を確認する

WSLでsystemctlが使えない|PID 1とsystemdの状態を確認する

WSLでサービスを確認しようとしてsystemctlを実行したら、PID 1やバス接続のエラーになった。systemctl自体は入っているのに動かないと、パッケージを入れ直すべきか、WSLの設定を変えるべきか迷いやすいところです。

手がかりになるのは、Linuxの最初のプロセスとして何が動いているかです。systemctlのバージョンが表示されることと、systemdがサービスを管理していることは同じではありません。WSLの条件、PID 1、目的のサービスの順に見ると、設定とサービス固有の問題を整理しやすくなります。


WSLの版と実行方式を見る

WindowsのPowerShellで次を実行します。

wsl --version
wsl --list --verbose

systemd対応に必要なWSL本体のバージョンは0.67.6以降で、ディストリビューションはWSL 2で動いている必要があります。一覧のVERSION列にある1や2は実行方式で、WSL本体の3.xなどの製品バージョンとは別です。

Microsoftは現在の標準Ubuntuについてsystemdが既定で有効と案内しています。ただし、以前から使っている環境や別のディストリビューション、手動で取り込んだ環境まで同じ初期状態とは限りません。すでに有効な環境へ設定を追加する前に、Linux側の状態を見るのが近道です。

Linux側のPID 1を確認する

調べたいディストリビューションのLinuxターミナルで実行します。

ps -p 1 -o comm=
systemctl --version

最初の行はPID 1のプロセス名、次はsystemctlのバージョンです。PID 1がsystemdなら、systemdを使う起動方式になっています。systemctlの版だけが表示されても、PID 1が別のプロセスならシステムのサービス管理に接続できないことがあります。

例えば、systemdがPID 1として動いていない環境では、サービスの状態取得で次のようなエラーが出ます。

System has not been booted with systemd as init system (PID 1). Can't operate.

この場合は、サービス名やアプリケーションの設定より先に起動方式を見直します。systemctlが見つからない場合はパッケージの有無からの確認です。UbuntuやDebianでは、Microsoftの手順でsystemdに加えてsystemd-sysvの導入も案内されています。コマンドがない状態と、コマンドはあるが管理先が動いていない状態では、次に調べる場所が変わります。

必要な場合にwsl.confを変更する

WSL 2でsystemdを使う条件が揃い、まだ有効になっていない場合は、そのディストリビューションの/etc/wsl.confを管理権限のあるエディターで開きます。変更前の内容を別に保存し、既存の設定を残したまま[boot]内に次の設定を合わせます。

[boot]
systemd=true

すでに[boot]がある場合は同じセクションを重複して追加せず、systemdの値を見直します。Windowsのユーザーフォルダーに置く.wslconfigとは別のファイルで、変更はそのLinux環境に関わります。

適用のために対象のディストリビューションを終了すると、その中のターミナル、開発サーバー、実行中の処理も止まります。作業を保存し、必要な処理を終了してから、WindowsのPowerShellで登録名を指定します。次のUbuntuは一覧に表示された実際の登録名へ置き換えてください。

wsl --terminate Ubuntu

対象を開き直したら、もう一度PID 1を確認します。systemdへ変わっていなければ、対象の登録名、ファイル名、設定の置き場所と内容を見直す順番です。元へ戻す場合も、保存しておいた設定へ戻してから、対象の作業を終えて終了・再起動し、PID 1を確かめます。

サービスの登録と実行状態を見比べる

systemdが動いていることが分かったら、サービスの定義を一覧にできます。

systemctl list-unit-files --type=service --no-pager

ここで表示されるenabledやdisabledは、主に起動時の有効化に関わる状態です。現在動いているかどうかを示すactiveとは別です。また、この一覧はsystemdがPID 1ではない状態でも表示できる場合があるため、一覧が出たことだけを有効化の判定には使えません。

個別の状態はstatusで読みます。次はsystemdのログを扱うsystemd-journald.serviceの確認例です。目的のアプリケーションを調べるときは、実際のサービス名に置き換えます。

systemctl status systemd-journald.service --no-pager

Loadedは定義の読み込み、Activeは実行状態の手がかりです。not-foundならサービス名や導入状態、failedならそのサービスのエラーへ進めます。enabledにしただけで今すぐ開始するわけではなく、startとenableは役割が異なります。最初からサービスを再インストールしたり、関係のないサービスを再起動したりするより、どこで止まっているかを先に読むほうが原因を絞れます。

サービス管理と常時稼働を分けて考える

systemdを使えるようになると、対応アプリケーションをLinuxのサービスとして管理できます。ただしMicrosoftは、systemdのサービス自体がWSLインスタンスを常に生かし続けるわけではないと説明しています。Windowsを再起動した後やWSLを終了した後も、サーバーがずっと動くことを保証する仕組みとは考えず、必要な稼働条件をアプリケーション側と合わせて検討することになります。

サービスは動いているのにWindowsのブラウザーから開けない場合は、localhostと待ち受けポートの確認手順が次の手がかりです。設定変更前に環境を残したい場合は、別名で復元して確認するWSLバックアップも役立ちます。

参考資料

このブラウザからの自分のアクセスを解析から除外できます。