複数の systemd サービスが 1 つのタイマーを使用するように設定するにはどうすればよいですか?

複数の systemd サービスが 1 つのタイマーを使用するように設定するにはどうすればよいですか?

1 つ以上のサービスが同じタイマーを使用するように構成する方法に関する一部の systemd ドキュメントとハウツー ドキュメントでは、アプローチに大きな違いがあることに気付きました。

私がまとめた限りでは(間違っているかもしれないが)、これは募集者そしてユニットサービスおよびタイマー ファイル内のパラメータは、単一のサービスの場合は次のように設定する必要があります (投稿の長さを短くするため、ここでは実際のコード例は使用しません)。また、単一のタイマーを使用する複数のサービス構成の場合は次のように設定する必要があります。

単一サービスのタイマー

My.Service1 'WantedBy' Param: N/A (1)
My.Timer 'Unit' Param: My.Service1 (2)
My.Timer 'WantedBy' Param: MultiUser/Basic.Target (3) 

(1)サービス ファイルには、WantedBy パラメータを含む [Install] セクションは必要ありません。

(2)タイマーの [Timer] セクションでは、Unit パラメータが My.Service1 サービス ファイルを指す必要があります。

(3)タイマー ファイルには、タイマーを起動するために使用される特別なシステム ターゲットを指す WantedBy パラメーターがあります。

複数のサービス用のタイマー

My.Service1 'WantedBy' Param: Timer.Target (1)
My.Service2 'WantedBy' Param: Timer.Target (1)
My.Service3 'WantedBy' Param: Timer.Target (1)
Timer 'Unit' Param: Timer.Target (2)
Timer 'WantedBy' Param: ???

(1)すべてのサービスは、WantedBy パラメータを使用して同じ定義済みターゲットに接続する必要があります。

(2)[タイマー] ユニット パラメータもターゲットを指す必要があります。

後者の構成の例については、このハウツーこれを例 1 としてカウントします。ただし、これとは異なる他のハウツー例も見つかりました (以下を参照)。

例2そして例3次のように設定する必要があります。

My.Service1 WantedBy: Timer.Target
My.Service2 WantedBy: Timer.Target
My.Service3 WantedBy: Timer.Target
Timer 'Unit' Param: My.Service1 (1)
Timer 'WantedBy' Param: MultiUser/Basic.Target

(1) これはドキュメントの見落としであるに違いありません。なぜなら、ユニットを複数のサービスのうちの 1 つだけを指すようにしておくと、他のサービスはタイマーを使用できないからです。おそらく、これは、実際に (重要な) 変更が必要な点について言及せずに、読者を単一のサービス構成に戻すために使用された「上記を参照」アプローチによるものでしょう。

そして例4その構成は実際に動作するように見えますが、サービスファイルを直接作成することで、サービスをターゲットに接続する方法が異なります。タイマーターゲットサブディレクトリを削除し、サービス ファイル内の WantedBy パラメータを除外します。つまり、

My.Service1 'WantedBy' Param: N/A
My.Service2 'WantedBy' Param: N/A
My.Service3 'WantedBy' Param: N/A
Timer 'Unit' Param: Timer.Target
Timer 'WantedBy' Param: MultiUser/Basic.Target

私が見た例1と例4のハイブリッドアプローチは、サービスファイルをシステムディレクトリ(デフォルトの場所)にサービスファイルへのシンボリックリンクを作成し、/etc/systemd/system/Timer.Target.wantsファイルと除外するサービス ファイルに WantedBy パラメータが含まれています (機能的には例 4 と同等)。一方、別の構成ではシンボリック リンク メソッドが使用されていますが、さらにサービス ファイルに WantedBy パラメータが含まれています (冗長で不必要と思われます)。

しかし、例4とハイブリッドアプローチに関して、私の質問は次のようになります。*。望むWantedByパラメータを宣言することでsystemdにそのように指示するのであれば、ディレクトリはまったく必要ありません(そのパラメータの説明に記載されているように)このページ)?

これを行うためのさまざまなアプローチが混乱を招く中で、同じタイマーを使用して複数のサービスを構成するための最良の方法を誰か明らかにできますか?

答え1

1 つのタイマーで複数のサービスをアクティブ化する場合は、間にターゲットを挿入します。

タイマーユニットを次のように呼びますfoo.timer

[Unit]
Description=My timer that runs saturdays, 9am and triggers foo.target
Wants=foo.target

[Timer]
OnCalendar=Sat 9:00
Unit=foo.target

[Install]
WantedBy=timers.target

ターゲットユニットを次のように呼びますfoo.target

[Unit]
Description=My target unit, that groups my two services xxx.service and yyy.service
Wants=xxx.service yyy.service
After=xxx.service yyy.service

[Install]
Also=foo.timer

そして、2 つのサービスxxx.serviceyyy.service:

[Unit]
Description=My service XXX

[Service]
ExecStart=/bin/echo I am XXX

[Install]
Also=foo.timer
[Unit]
Description=My service YYY

[Service]
ExecStart=/bin/echo I am YYYY

[Install]
Also=foo.timer

これらの 4 つのユニット ファイル ( foo.timer、、、)を にコピーします。次に、次foo.targetのコマンドを実行してタイマーを有効にして開始します。xxx.serviceyyy.service/etc/systemd/systemd/

systemctl enable --now foo.timer` 

これは、システムで定義されているさまざまなタイマーをすべて取り込むことになっている汎用ターゲットであるfoo.timerにフックします。timers.target

なお、これらのユニットの行は有効化要求を に伝播するためsystemctl enable foo.target、 btw および も実行できることに注意してください。systemctl enable zzz.serviceAlso=foo.timer

答え2

systemd タイマーは常に 1 つのユニットをアクティブにします。

同じスケジュールで 2 つのユニットをアクティブ化する場合は、わかりやすくするために、同じスケジュールを含む 2 つのタイマー ファイルを作成することをお勧めします。

それ以外の場合は、必要な 2 つのサービスを起動する「サービス ユニット」ファイルを作成することもできます。

「WantedBy=」はタイマーユニットにとって特に便利な概念ではないと思います。

関連情報