複数のインスタンスを同時に停止/起動する仮想 systemd サービスを作成するにはどうすればよいですか?

複数のインスタンスを同時に停止/起動する仮想 systemd サービスを作成するにはどうすればよいですか?

を使用する顧客向けに、同じ Web アプリの複数のインスタンスをホストする予定です。を使用する各顧客インスタンスを およびsystemdできるようにし、顧客インスタンスのコレクション全体を、まとめて停止および開始できる単一のサービスとして扱えるようにしたいと考えています。stopstartsystemd

systemd、およびテンプレート ユニット ファイルを使用して必要なビルディング ブロックを提供しているようですPartOfが、親サービスを停止しても、子カスタマー サービスは停止されません。これを systemd で動作させるにはどうすればよいですか? これまでのところ、次のようになっています。

親ユニットファイルapp.service:

[Unit]
Description=App Web Service

[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal

[email protected]顧客インスタンスを作成するために使用される という名前のユニット テンプレート ファイル:

[Unit]
Description=%I Instance of App Web Service

[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal

私のapp-poc.shスクリプト (ループ内でログ ファイルに印刷するだけの概念実証):

#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
  echo "The App PoC loop for $@"
  sleep 2;
done

概念実証のために、systemd ユニット ファイルを に用意しました~/.config/systemd/user

次に、テンプレートに基づいて親とインスタンスを起動します (後systemctl --user daemon-reload)。

systemctl --user start app
systemctl --user start [email protected]

使用してみるとjournalctl -f、両方が起動し、顧客インスタンスが引き続き実行されていることがわかります。親をシャットダウンすると、子も停止すると思います(使用したため)PartOf) ですが、起動しません。また、親を起動しても、期待どおりに子が起動しません。

systemctl --user stop app

ありがとう!

(私はsystemd 229を搭載したUbuntu 16.04を使用しています)。

答え1

これが systemd の「ターゲット ユニット」の目的だとわかりました。ターゲット ユニットを使用すると、上記の偽のセクションを作成しなくても、必要な利点が得られます[Service]。実際の「ターゲット ユニット」ファイルの例は次のようになります。

# named like app.target
[Unit]
Description=App Web Service

# This collection of apps should be started at boot time.
[Install]
WantedBy=multi-user.target

次に、各顧客インスタンスPartOf[Unit]セクションを含める必要があります (@meuh が指摘したように)。また、が特定のサービスで機能する[Install]ように セクションも含める必要があります。enabledisable

# In a file name like [email protected]
[Unit]
Description=%I Instance of App Web Service
PartOf=app.target

[Service]
ExecStart=/home/mark/bin/app-poc.sh %i
Restart=on-failure
StandardOutput=journal

# When the service runs globally, make it run as a particular user for added security
#User=myapp
#Group=myapp

# When systemctl enable is used, make this start when the App service starts
[Install]
WantedBy=app.target

顧客インスタンスを起動し、ターゲットの起動時に起動させるには、次の 1 回限りの有効化コマンドを使用します。

 systemctl enable app

この時点で、stopと を使用して特定のインスタンスをstart実行したり、 とを使用してすべてのアプリを同時に停止したりできます。app@customerstart appstop app

答え2

線を移動する必要がある

PartOf=app.service

セクションから[Service]セクションへ[Unit]、そして開始する顧客リストの に追加します。例[Unit]:app.service

[email protected] [email protected]

または、sourcejedi がコメントで述べたように、Requires=同じことです。 を保持して、PartOfなどの上記のリストにない手動で開始したサービスを停止することができます。systemctl --user start [email protected]

関連情報