Help us understand the problem. What is going on with this article?

WSL2でSystemdを使うハック

initについて

Linuxを含むUnix系OSの起動に使われるシステム。カーネルから最初に起動され、プロセスID 1が付与され、ほかのすべてのプロセスの先祖として動作し、さまざま初期処理を行うプログラム。

Linuxでは、SysVInit → Upstart → Systemd のように置き換えれらてきた。

WSLのinitについて

WSLはMSによるカスタムのinitを使っている。Windowsとの相互運用に必要な重要な処理を行っており、置き換えられない。一方で、Systemdのような高度なことは行わない。

Systemdもインストールはされるが、無効化されている。有効にしようとしても、PID 1で動作しないので、systemctl によるサービス管理がエラーになる。

systemd を PID 1 で動かす方法(基本方針編)

Ubuntuのコミュニティサイトに Using snapd in WSL2 という投稿があったので解説してみる。

unshare コマンドで簡易コンテナーを作る

最初に、以下のコマンドを実行する。

sudo daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target 

unshare コマンドは、実行コンテキストに名前空間を割り当てて、ほかのプロセスから分離する。
オプションは以下のものを指定している。

  • --fork : 指定したプログラム(/lib/systemd/systemd --system-unit=basic.target)をunshareの子プロセスとしてforkさせる
  • --pid : PID 名前空間を分離する
  • --mount-proc : マウント名前空間を分離し、/proc を再マウントする

systemd コマンドは、unshare によって、隔離された名前空間のPID 1として起動する。なお、マルチユーザーの基本サービスが定義された basic.target がターゲットとして指定されている。

そして、それら全体を現在のシェルから切り離してデーモン化するため、demonize コマンドを使用している。

この時点で systemd はPID 1として動き出すものの、あくまで隔離された簡易コンテナー環境の中だけの話である。簡易コンテナーの外でサービスを管理しようとすると、簡易コンテナーの中の systemd と通信できずに失敗する。

nsenter コマンドで簡易コンテナーの中に入る

というわけで、サービスを管理する場合は簡易コンテナーに入らないといけない。それには、以下のコマンドを実行する。

exec sudo nsenter --target $(pidof systemd) --all su - $LOGNAME

nsenter コマンドは、隔離された名前空間を持つ簡易コンテナ―に入ってプログラムを実行する。オプションは以下のものを指定している。

  • --target $(pidof systemd) : 簡易コンテナ―として隔離実行されている systemd の実際の PID をターゲットとして指定
  • --all : ターゲットプロセスのすべての名前空間をマウントしなおす。
  • su - $LOGNAME : 現在のログインユーザーとしてログインしなおす。

そして、現在のプロセスを置き換えるため、 exec コマンドを使用している。

ここまで成功すれば、systemctl でも snap でも動かせるようになっているはず。

systemd を PID 1 で動かす方法(派生編)

この方法で起動した systemdnsenter は、永続的ではないので、毎回実行しないといけない。

systemd は、Windowsを再起動して最初にWSL2を実行するときに実行しておく必要がある。

nsenter は、WSL2を実行するたびに毎回最初に実行しておく必要がある。

これらを毎回実行するのが面倒な人には、次の3つの方法を紹介する。

genie コマンド

https://github.com/arkane-systems/genie/

genie コマンドは、 unsharensenter のラッパー的なコマンド。コマンド名は、瓶(コンテナー)に封じられた魔法の精1から。

インストール方法と使い方は上記githubのreadmeを参照のこと。

/etc/bash.bashrc で自動実行させる

方法は下記のリンク先に書いてある通り。

https://forum.snapcraft.io/t/running-snaps-on-wsl2-insiders-only-for-now/13033

一応、手順を簡単に解説しておく。

  • /usr/sbin/start-systemd-namespace/usr/sbin/enter-systemd-namespace という2つのスクリプトファイルを作成しておく
  • /usr/sbin/start-systemd-namespaceの中で実行する sudo /usr/sbin/enter-systemd-namespace コマンドにはパスワードが不要なように設定しておく
  • /etc/bash.bashrcsource /usr/sbin/start-systemd-namespace を実行するようにしておく
  • 環境変数 BASH_ENV/etc/bash.bashrc を設定しておく(Windows側に %WSLENV% を設定して引き継ぐ)

sudoコマンドの設定は sudo visudoコマンドを使って /etc/sudoers ファイルを編集するのが基本だが、今回の /usr/sbin/enter-systemd-namespace のための設定は /etc/sudoers.d/ ディレクトリに切り出しておくのもよい。その方法を紹介しているページはこちら

ログインシェルを置き換える

方法は下記のリンク先に書いてある通り。

https://github.com/shayne/wsl2-hacks

一応、手順を簡単に解説しておく。

  • /usr/bin/bash スクリプトファイルを作成しておく
  • /etc/passwd ファイルを編集して、rootユーザーのログインシェルを /usr/bin/bash に設定する
  • ログインユーザーをrootにする
    • Linuxディストリビューションをストアアプリとしてインストールしている場合は [ディストリビューション名].exe --config --default-user root を実行する
    • そうでない場合は wsl.exe [ディストリビューション名] コマンドで起動する際にユーザーを指定しなければrootユーザーで起動するはず

一応紹介はしたものの、2番目の bash.bashrc で自動実行させる方法の方がおすすめ。


  1. 「アラジンと魔法のランプ」の方が有名だけど、あの話、原典の千夜一夜物語には収録されていないらしいよ。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした