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


12

を使用しているお客様のために、同じWebアプリの複数のインスタンスをホストする予定ですsystemd。を使用して、各顧客インスタンスを処理できるようにしたい。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

という名前のユニットテンプレートファイル。app@.service顧客インスタンスの作成に使用されます。

[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 app@customer.service

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

systemctl --user stop app

ありがとう!

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


1
「PartOf =は、Requires =と同様の依存関係を構成しますが、ユニットの停止と再起動に限定されます。」仕事を始めたいなら、Requires=代わりに使う必要はありませんか?
sourcejedi 2016年

回答:


10

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

PartOf=app.service

うち、[Service]とに[Unit]する部分、および追加[Unit]app.service顧客のリストを開始するには、たとえば、

Wants=app@customer1.service app@customer2.service

またはsourcejediがコメントで言ったようにRequires=、同じこと。PartOfのように、上記のリストにない手動で開始したサービスを停止しておくことができますsystemctl --user start app@customer3.service


あなたが正しかったことを確認しましたPartOf。ありがとう。systemdで新しい顧客をアクティブ化するために実行する必要がある単一のアクションとなるシンボリックリンクを介して「ウォント」を処理します。私のテストケースの場合: `ln -s /home/mark/.config/systemd/user/app@.service / home / mark / .config / systemd / user / app.service.wants / unity @ foo.service`
マーク・ストスバーグ2016年

13

これが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]ようにセクションをenableし、disable特定サービスに取り組みます。

# In a file name like app@.service
[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

今、この時点で、私が使用することができますstopし、startapp@customerに特定のインスタンスに対して、または私が使用することができますstart appし、stop app一緒にすべてのアプリケーションを停止します。


ステータスはどうですか?アプリが必要とするすべてのサービスのステータスを取得する簡単な方法が見つかりません。私はそれをどのようにスクリプト化できるか知っていますが、...
Tommi Kyntola

1
つまり、ワイルドカードの有無にかかわらず、その一部であるすべてをリストせずに、そのターゲットグループ内のアプリのステータスを取得するようなものです。できればそのグループ名を使用し、それが何で構成されているかさえ気にしないでください。
Tommi Kyntola

2
それはそれほど単純ではありません。そのスクリプトはどのパケットに属しますか?新しいコンポーネントが追加されるたびに変更する必要があります。それを忘れて、配備/保守は大雑把です。私が明らかに望んでいるのは、そのグループ内に存在することを示すpartOf設定を含む新しいパケットを追加するだけで、残りのスクリプトを変更しないことです。そして、そのターゲットの停止と開始は以前と同じように機能します。これは機能しますが、ステータスはその範囲から外れているようです。ターゲットに存在するランタイムのユニットのリストを取得する方法すら見つけられません。この使用例はsystemdではカバーされていません。
Tommi Kyntola

2
:@TommiKyntolaはここでターゲットが変更を依存関係として使用すると、更新する必要がないことをbashのワンライナーだsystemctl status $(systemctl list-dependencies --plain otp.target)
マーク・Stosberg

2
@TommiKyntola私systemdはここでユーザビリティを改善できることに同意します。私がしまし機能要求開かれたターゲットのための改良された状態を提案するが。
マークストースバーグ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.