web-dev-qa-db-ja.com

依存するサービスが再起動された場合にサービスを再起動する方法

サービス(bar.serviceなど)は、次のように別のサービス(foo.serviceなど)に依存しています

バーのサービスファイル:

[Unit]
After=foo.service
Requires=foo.service
...

Foo.serviceが(手動またはバグにより)再起動された場合、bar.serviceもどのように自動的に再起動されますか?

20
iobelix

PartOfを使用できます。

[Unit]
After=foo.service
Requires=foo.service
PartOf=foo.service

から systemd.unit manページ:

PartOf =

Requires =と同様の依存関係を設定しますが、ユニットの停止と再起動に限定されます。 systemdがここにリストされているユニットを停止または再起動すると、アクションがこのユニットに伝達されます。これは一方向の依存関係であることに注意してください。このユニットを変更しても、リストされているユニットには影響しません。

33
Kevin M Granger

別の解決策は、foo.serviceが(再)開始されたときにbar.service(実行されている場合)を再起動するExecStartPostオプションを使用することです。

# foo.service
[Service]
ExecStartPost=/bin/systemctl try-restart bar.service
Restart=on-failure
RestartSec=30s

追加のRestartおよびRestartSecオプションは、foo.serviceがクラッシュ時に自動的に再起動されるようにします。

2番目の拡張機能は、bar.serviceに同じものを追加し、foo.serviceの後にbar.serviceが開始されるようにします。

# bar.service
[Unit]
After=foo.service

[Service]
Restart=on-failure
RestartSec=30s

これにより、クラッシュの場合に両方のサービスが自動的に開始され、foo.serviceの再起動時にbar.serviceが再起動されます(エラーまたは手動でトリガーされたため)。

4
panticz

必要なオプションはBindsToであると思いますが、これも誤動作を処理します。

[Unit]
Requires=postgresql.service
After=postgresql.service
BindsTo=postgresql.service

BindsTo =

要件の依存関係を構成します。スタイルはRequires =に非常に似ています。ただし、この依存タイプはより強力です。Requires=の効果に加えて、バインドされているユニットが停止すると、このユニットも停止することを宣言します。これは、突然非アクティブ状態になった別のユニットにバインドされたユニットも停止することを意味します。ユニットは突然、さまざまな理由で非アクティブ状態になります:サービスユニットのメインプロセスが独自の選択で終了したり、デバイスユニットのバッキングデバイスが取り外されたり、マウントユニットのマウントポイントが関与せずにアンマウントされたりすることがありますシステムおよびサービスマネージャー。

同じユニットでAfter =と組み合わせて使用​​すると、BindsTo =の動作はさらに強力になります。この場合、このユニットもアクティブ状態になるには、バインド先のユニットが厳密にアクティブ状態になっている必要があります。これは、突然非アクティブ状態になる別のユニットにバインドされたユニットだけでなく、条件チェックの失敗によりスキップされる別のユニットにバインドされたユニット(ConditionPathExists =、ConditionPathIsSymbolicLink =、…—以下を参照)も意味します停止しており、実行されている必要があります。したがって、多くの場合、BindsTo =とAfter =を組み合わせることをお勧めします。

2
ego2dot0