web-dev-qa-db-ja.com

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

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

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

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

次に、テンプレートに基づいて親とインスタンスを起動します(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を使用しています)。

12
Mark Stosberg

行を移動する必要があります

PartOf=app.service

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

[email protected] [email protected]

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

10
meuh

これが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

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

# 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回限りのenableコマンドを使用します。

 systemctl enable app

この時点で、特定のインスタンスに対してapp@customerstopstartを使用するか、start appstop appを使用してすべてのアプリを一緒に停止できます。

14
Mark Stosberg