「Systemd/タイマー」の版間の差分
Kusanaginoturugi (トーク | 投稿記録) 細 (→サービス) |
(同期) |
||
4行目: | 4行目: | ||
[[en:Systemd/Timers]] |
[[en:Systemd/Timers]] |
||
[[fr:Systemd/cron]] |
[[fr:Systemd/cron]] |
||
+ | [[ru:Systemd/Timers]] |
||
[[zh-CN:Systemd/Timers]] |
[[zh-CN:Systemd/Timers]] |
||
{{Related articles start}} |
{{Related articles start}} |
||
77行目: | 78行目: | ||
WantedBy=timers.target</nowiki>}} |
WantedBy=timers.target</nowiki>}} |
||
− | {{Tip|{{ic|daily}} や {{ic|weekly}} などの特殊なイベントの表現は''特定の起動時間''を示しているため、同じカレンダーイベントが設定されているタイマーがあった場合、同時に起動します。そのようなことが発生すると、タイマーのサービスがシステムリソースを取り合って、システムパフォーマンスが落ち込む可能性があります。{{ic| |
+ | {{Tip|{{ic|daily}} や {{ic|weekly}} などの特殊なイベントの表現は''特定の起動時間''を示しているため、同じカレンダーイベントが設定されているタイマーがあった場合、同時に起動します。そのようなことが発生すると、タイマーのサービスがシステムリソースを取り合って、システムパフォーマンスが落ち込む可能性があります。このような問題は {{ic|RandomizedDelaySec}} オプションを使用してタイマーの起動時間を散らすことで解決できます。{{ic|systemd.timer (5)}} を参照してください。}} |
=== サービス === |
=== サービス === |
||
111行目: | 112行目: | ||
* 冗長性: ''systemd'' を使って定期的なジョブを設定するには2つのファイルを作成して2回 {{ic|systemctl}} コマンドを実行します。それに対して crontab には一行を追加するだけです。 |
* 冗長性: ''systemd'' を使って定期的なジョブを設定するには2つのファイルを作成して2回 {{ic|systemctl}} コマンドを実行します。それに対して crontab には一行を追加するだけです。 |
||
* メール: ジョブが失敗した時にメールを送信する cron の {{ic|MAILTO}} と同等なものは存在しません。ただし各サービスに {{ic|1=OnFailure=}} オプションを使うことで同じような機能を設定することはできます。 |
* メール: ジョブが失敗した時にメールを送信する cron の {{ic|MAILTO}} と同等なものは存在しません。ただし各サービスに {{ic|1=OnFailure=}} オプションを使うことで同じような機能を設定することはできます。 |
||
− | * ランダム遅延: インターバルを指定してタイマーの実行をランダムに分散する cron の {{ic|RANDOM_DELAY}} と同じ機能はありません ([https://bugs.freedesktop.org/show_bug.cgi?id=82084 バグレポート]や[https://wiki.archlinux.org/index.php?title=Talk:Systemd/Timers&oldid=356408#Parallelization_section_is_confusing テスト結果]を参照)。同時に実行して欲しくないサービスには、手動でオーバーラップを少なくするようにタイマーを設定する必要があります。 |
||
− | |||
− | :{{note|タイマーを自動的にずらすには {{ic|AccuracySec}} オプションが役に立つかもしれません。ただし"全てのローカルなタイマーユニット間で同期が行われる"ので注意してください ({{ic|systemd.timer(5)}})。言い換えれば、{{ic|AccuracySec}} は全てのタイマーの作動時間を同じ分だけずらします。例えば、{{ic|1=AccuracySec=15m}} を使っている {{ic|1=OnCalendar=daily}} のタイマーユニットは全て、00:00 から 00:15 の間の同一時刻に関連するサービスを起動します。}} |
||
=== MAILTO === |
=== MAILTO === |
||
133行目: | 131行目: | ||
どんな実行可能ファイルを使うのであれ、上記のシェルスクリプトのように、最低でも2つの引数が必要になります: 送信先のアドレスと状態を取得するユニットファイルです。以下の ''.service'' はそれらの引数を渡します: |
どんな実行可能ファイルを使うのであれ、上記のシェルスクリプトのように、最低でも2つの引数が必要になります: 送信先のアドレスと状態を取得するユニットファイルです。以下の ''.service'' はそれらの引数を渡します: |
||
− | {{hc|/etc/systemd/system/status-email- |
+ | {{hc|/etc/systemd/system/status-email-''user''@.service|2=[Unit] |
− | Description=status email for %I to |
+ | Description=status email for %I to ''user'' |
[Service] |
[Service] |
||
Type=oneshot |
Type=oneshot |
||
− | ExecStart=/usr/local/bin/systemd-email |
+ | ExecStart=/usr/local/bin/systemd-email ''address'' %i |
User=nobody |
User=nobody |
||
− | Group=systemd-journal |
+ | Group=systemd-journal}} |
− | </nowiki>}} |
||
− | |||
− | メールを送信するユニットがインスタンスパラメータになっていることに気づいて下さい。これによって、他のユニットでメールを送信するのにも使えるようになっています。ただしメールの受取人はハードコードされています (ユニットテンプレートが使用できるパラメータは一つだけのため)。メールを様々なところに送りたい場合は複数のサービスを作成する必要があります。サービスを作成したら、メールがちゃんと受け取れるかどうかテストしてみてください: |
||
+ | {{ic|''user''}} はメールを送信するユーザーに、{{ic|''address''}} はユーザーのメールアドレスに置き換えてください。受信者はハードコードされますが、インスタンスパラメータとしてユニットファイルを渡すことで、上記のサービスだけで他のユニットのメールも送ることができます。{{ic|status-email-''user''@dbus.service}} を[[systemd#ユニットを使う|起動]]して、メールが受け取れることを確認してください。 |
||
− | {{bc|# systemctl start status-email-user1@dbus.service}} |
||
− | 問題ないようでしたら、メールを送って欲しいユニットの {{ic|[Unit]}} セクションに {{ic|1=OnFailure=status-email- |
+ | 問題ないようでしたら、メールを送って欲しいユニットの {{ic|[Unit]}} セクションに {{ic|1=OnFailure=status-email-''user''@%n.service}} を追加してください。{{ic|%n}} はユニットの名前をテンプレートに指定します。 |
+ | {{note| |
||
− | {{note|[[SSMTP#セキュリティ]] にしたがって SSMTP を設定した場合、ユーザー {{ic|nobody}} は {{ic|/etc/ssmtp/ssmtp.conf}} にアクセスすることができず、{{ic|systemctl start status-email-user1@dbus.service}} コマンドは失敗します。{{ic|status-email-user1@.service}} モジュールの User に {{ic|root}} を使うことでこれを回避できます。}} |
||
+ | *[[SSMTP#セキュリティ]] にしたがって SSMTP を設定した場合、ユーザー {{ic|nobody}} は {{ic|/etc/ssmtp/ssmtp.conf}} にアクセスすることができず、{{ic|systemctl start status-email-''user''@dbus.service}} コマンドは失敗します。{{ic|status-email-''user''@.service}} モジュールの User に {{ic|root}} を使うことでこれを回避できます。 |
||
+ | * メールスクリプトで {{ic|mail -s somelogs ''address''}} を使用すると、{{ic|mail}} はフォークして、systemd はスクリプトの終了を確認したときに mail プロセスを終了します。{{ic|mail -Ssendwait -s somelogs ''address''}} として mail がフォークしないようにしてください。}} |
||
=== crontab を使用する === |
=== crontab を使用する === |
||
− | crontab を使って定期的なサービスを管理するツールとして {{aur|systemd- |
+ | crontab を使って定期的なサービスを管理するツールとして {{aur|systemd-cron-next}} と {{aur|systemd-cron}} があります。どちらも [[AUR]] からインストールすることができます。これらのツールには systemd に存在しない {{ic|MAILTO}} 機能が実装されています。 |
もし、スケジュールされたジョブをまとめて見れるから crontab が好きだという場合は、{{ic|systemctl}} でそれと同じことが可能です。[[#管理]] を見て下さい。 |
もし、スケジュールされたジョブをまとめて見れるから crontab が好きだという場合は、{{ic|systemctl}} でそれと同じことが可能です。[[#管理]] を見て下さい。 |
||
162行目: | 159行目: | ||
* [https://fedoraproject.org/wiki/Features/SystemdCalendarTimers Fedora Project wiki] の ''systemd'' カレンダータイマーのページ |
* [https://fedoraproject.org/wiki/Features/SystemdCalendarTimers Fedora Project wiki] の ''systemd'' カレンダータイマーのページ |
||
* [https://wiki.gentoo.org/wiki/Systemd#Timer_services Gentoo wiki] の ''systemd'' タイマーサービスのセクション |
* [https://wiki.gentoo.org/wiki/Systemd#Timer_services Gentoo wiki] の ''systemd'' タイマーサービスのセクション |
||
− | * {{App|systemd- |
+ | * {{App|systemd-cron-next|crontab と anacrontab ファイルからタイマーとサービスを生成するツール|https://github.com/kstep/systemd-cron-next|{{Aur|systemd-cron-next}}}} |
* {{App|systemd-cron|cron スクリプトを実行する systemd ユニットが入っています。''systemd-crontab-generator'' を使って crontab を変換。|https://github.com/systemd-cron/systemd-cron|{{Aur|systemd-cron}}}} |
* {{App|systemd-cron|cron スクリプトを実行する systemd ユニットが入っています。''systemd-crontab-generator'' を使って crontab を変換。|https://github.com/systemd-cron/systemd-cron|{{Aur|systemd-cron}}}} |
2016年4月24日 (日) 00:28時点における版
タイマーは名前が .timer
で終わる systemd のユニットファイルであり、.service
ファイルやイベントを制御します。cron の代わりとしてタイマーを使うことができます (#cron を置き換える を読んで下さい)。タイマーにはカレンダー時刻のイベントとモノトニック時刻のイベントのサポートが入っており、さらに非同期に実行することも可能です。
目次
タイマーユニット
タイマーは拡張子が .timer
の systemd のユニットファイルです。他のユニット設定ファイルと似ていますが特別に [Timer]
セクションが存在します。[Timer]
セクションにはタイマーが作動する時間と処理を定義します。タイマーには2つのタイプがあり、どちらか一つを使って定義されます:
- モノトニックタイマーは刻々と変わる開始点と相応したタイムスパンの後に作動します。様々なモノトニックタイマーが存在しますがどれも次のような形式です:
OnTypeSec=
。OnBootSec
とOnActiveSec
は全てのモノトニックタイマーで共通です。 - リアルタイムタイマー (別名ウォールクロックタイマー) は (cron のジョブと同じように) カレンダーイベントにあわせて作動します。
OnCalendar=
オプションを使って定義を行います。
タイマーのオプションについては systemd.timer(5)
の man ページで説明されています。カレンダーイベントやタイムスパンの引数構文については systemd.time(7)
の man ページで説明されています。
サービスユニット
それぞれの .timer
ファイルには、対応する .service
ファイルが存在します (例: foo.timer
と foo.service
)。.timer
ファイルは .service
ファイルを作動・制御します。.service
に [Install]
セクションは必要ありません。有効にするのは timer ユニットだからです。必要ならば、タイマーの [Timer]
セクションで Unit=
オプションを使うことで別の名前のユニットを制御することもできます。
管理
timer ユニットを使用するには、他のユニットと同じように有効化・起動します。起動しているタイマーを全て表示するには、次を実行:
$ systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2014-07-10 19:37:03 CEST 11h left Wed 2014-07-09 19:37:03 CEST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Fri 2014-07-11 00:00:00 CEST 15h left Thu 2014-07-10 00:00:13 CEST 8h ago logrotate.timer logrotate.service
サンプル
タイマーを使用してサービスを実行するのにあたって、service ユニットファイルに変更を加える必要はありません。以下の例では foo.timer
という名前のタイマーを使って foo.service
を定期的に実行します。
モノトニックタイマー
起動15分後に実行され、システムが起動している間、一週間ごとに再度実行されるタイマー:
/etc/systemd/system/foo.timer
[Unit] Description=Run foo weekly and on boot [Timer] OnBootSec=15min OnUnitActiveSec=1w [Install] WantedBy=timers.target
リアルタイムタイマー
一週間ごとに起動するタイマー (月曜日の午前12:00に実行)。システムの電源が切られていたなどの理由で、最後の起動時間を過ぎていた場合、すぐに実行されます (Persistent=true
オプション):
/etc/systemd/system/foo.timer
[Unit] Description=Run foo weekly [Timer] OnCalendar=weekly Persistent=true [Install] WantedBy=timers.target
サービス
/etc/systemd/system/foo.service
[Unit] Description=daily foo RefuseManualStart=no RefuseManualStop=yes [Service] Type=oneshot ExecStart=/home/<user>/scripts/foo.sh
cron を置き換える
おそらく一番有名なジョブスケジューラは cron ですが、systemd のタイマーはその代替手段になりえます。
メリット
タイマーを使う主要なメリットは、それぞれのジョブが固有の systemd サービスを使うというところに根ざします。そのメリットには以下のようなものがあります:
- タイマーとは別個にジョブを実行することが簡単にできます。これによってデバッグが楽になります。
- 特定の環境で動作するようにジョブを設定することができます (
systemd.exec(5)
man ページを参照)。 - ジョブを cgroups の支配下に置けます。
- 他の systemd ユニットに依存するようにジョブを設定できます。
- systemd の journal でジョブが記録されるのでデバッグが簡単です。
注意事項
cron では簡単にできることが、タイマーユニットを使用する場合、難しかったり不可能であったりすることがいくつか存在します。
- 冗長性: systemd を使って定期的なジョブを設定するには2つのファイルを作成して2回
systemctl
コマンドを実行します。それに対して crontab には一行を追加するだけです。 - メール: ジョブが失敗した時にメールを送信する cron の
MAILTO
と同等なものは存在しません。ただし各サービスにOnFailure=
オプションを使うことで同じような機能を設定することはできます。
MAILTO
Cron の MAILTO
のように、systemd で、ユニットが失敗したときにメールを送信するように設定できます。それにはまず2つのファイルが必要です: メールを送信するための実行可能ファイルと、実行可能ファイルを起動するための .service。以下の例では、sendmail
を使用するシェルスクリプトが実行可能ファイルになっています:
/usr/local/bin/systemd-email
#!/bin/bash /usr/bin/sendmail -t <<ERRMAIL To: $1 From: systemd <root@$HOSTNAME> Subject: $2 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 $(systemctl status --full "$2") ERRMAIL
どんな実行可能ファイルを使うのであれ、上記のシェルスクリプトのように、最低でも2つの引数が必要になります: 送信先のアドレスと状態を取得するユニットファイルです。以下の .service はそれらの引数を渡します:
/etc/systemd/system/status-email-user@.service
[Unit] Description=status email for %I to user [Service] Type=oneshot ExecStart=/usr/local/bin/systemd-email address %i User=nobody Group=systemd-journal
user
はメールを送信するユーザーに、address
はユーザーのメールアドレスに置き換えてください。受信者はハードコードされますが、インスタンスパラメータとしてユニットファイルを渡すことで、上記のサービスだけで他のユニットのメールも送ることができます。status-email-user@dbus.service
を起動して、メールが受け取れることを確認してください。
問題ないようでしたら、メールを送って欲しいユニットの [Unit]
セクションに OnFailure=status-email-user@%n.service
を追加してください。%n
はユニットの名前をテンプレートに指定します。
crontab を使用する
crontab を使って定期的なサービスを管理するツールとして systemd-cron-nextAUR と systemd-cronAUR があります。どちらも AUR からインストールすることができます。これらのツールには systemd に存在しない MAILTO
機能が実装されています。
もし、スケジュールされたジョブをまとめて見れるから crontab が好きだという場合は、systemctl
でそれと同じことが可能です。#管理 を見て下さい。
参照
- systemd.timer man page on freedesktop.org
- Fedora Project wiki の systemd カレンダータイマーのページ
- Gentoo wiki の systemd タイマーサービスのセクション
- systemd-cron-next — crontab と anacrontab ファイルからタイマーとサービスを生成するツール
- systemd-cron — cron スクリプトを実行する systemd ユニットが入っています。systemd-crontab-generator を使って crontab を変換。