systemd-nspawnコンテナが起動するのを待つ方法は?

systemd-nspawnコンテナが起動するのを待つ方法は?

次の内容のスクリプトがあります。

sudo machinectl start "$machinename"
sudo systemd-run -PM root@"$machinename" "$command"
Failed to connect to bus: No such file or directory
Failed to start transient service unit: Transport endpoint is not connected

最初の行はコンテナを起動するため失敗します。 2行目は、コンテナの起動が完了する前に実行されます。現在、コンテナの状態をポーリングし続け、準備が整うまでブロックするソリューションがあります。

while [ "$(sudo systemctl show "systemd-nspawn@$machinename" -P StatusText)" != "Container running: Ready." ]
do
true
done

コンテナの状態を継続的にポーリングせずにコンテナの起動が完了するまでどのように待つことができますか?

答え1

やりたいことによって異なります。あなたの質問に直接答えて、いくつかの選択肢を提供します。コンテナからinitシステムとしてsystemdを使用しているとします。コンテナOSがDebian / Arch / Ubuntuまたはそれに似た基盤である場合は実際にはそうです。

nspawn コンテナの起動後にコマンドを実行します。

.nspawnファイル(/etc/systemd/nspawn/yourcontainer.nspawn)に以下を追加します。

[Exec]
NotifyReady=yes

次に、sudo machinectl start yourcontainerコンテナが終了する前に起動が完了するのを待ちます。コンテナが準備されたので、スクリプトの2行目が機能します(コンテナが起動しないため、ポーリングが無限ループに陥らない限り)。

内部的には、ホストはsystemd-nspawnコンテナにUnixドメインソケットを設定しています。/run/host/notifyコンテナの systemd が準備されると (つまり、ターゲットmulti-user.targetに到達すると)、READY=1そのソケットに通知を送信します。ホストのsystemd-nspawnサービスがメッセージの受信を待っています。

このアプローチの欠点は、コンテナを非同期で起動できないことです(&シンボルを使用しない限り)。これはデバッグ中で、起動時間が長い場合は迷惑になる可能性があります。

その他の方法(複雑度順):

chrootでコマンドを実行する

コンテナが実行されていないと仮定すると、

sudo chroot /var/lib/machines/yourcontainer /bin/bash -c "$command"

これは、コンテナを作成してプログラムで複数回初期化した場合に便利です。明らかに、サンドボックス機能の利点を得ることができないようです。PrivateUsers=yesファイルはchown高いUIDで編集されるため、以前に同じコンテナを実行しても機能しません。コンテナがすでに実行されている場合、未定義の結果が表示されることがあります。

systemd-nspawnを直接使用する

この方法は果たしていいえNotifyReady=yes|no上記の説明が必要です。

systemd-nspawn -M yourcontainer -P /bin/bash -c "$command"

これにより、すべてのサンドボックスがアクティブなコンテナ内でコマンドが実行されますが、コマンドは唯一のプロセスとして(およびPID=1)実行されます。つまり、initサービスは実行されません。たとえば、ホストネットワーキングを使用しない限り、ネットワーキングは使用できません。

コンテナがすでに実行されている場合、このコマンドは何もしません。

ソケットの有効化

コンテナのサーバーが準備されるのを待つ場合は、ソケットアクティベーションを使用できます(サーバーが互換性があると仮定)。これは他の場所でより良い説明要約すると、systemdはソケット(TCPポート80など)への接続を待ちます。クライアントが接続されると、systemd はコンテナを起動し、コンテナにトラフィックを転送します。古代にもinetd同じことが行われました。

これにはファイル[email protected]内のものと同じ行が必要です.socket

関連情報