Systemd Timer Unitをマスターする:総合ガイド
Linuxで広く使用されているシステムおよびサービスマネージャーであるSystemdは、タスクスケジューリングにおいて、従来のcronジョブに代わる強力で柔軟な選択肢を提供します。Systemdエコシステムに直接組み込まれている機能であるSystemdタイマーユニットは、強化された制御、システムサービスとのより優れた統合、およびより詳細なロギング機能を提供します。このガイドでは、Systemdタイマーユニットの作成、管理、および監視のプロセスを順を追って説明し、タスクを自信と効率性をもって自動化できるようにします。
cronは何十年もの間、タスクスケジューリングの定番でしたが、Systemdタイマーはいくつかの利点を提供します。これらはサービスユニットに直接結びつけることができるため、システムが準備できたときにのみタイマーがサービスをアクティブ化したり、タイマーが完了する前に期限切れになった場合にサービスを停止したりできます。この緊密な統合により、複雑な依存関係の管理が簡素化されます。さらに、Systemdのロギングインフラストラクチャ(journald)は、すべてのタイマーアクティビティに対して一元化され、検索可能なログを提供するため、散在するcronログをふるいにかけるよりもデバッグが大幅に容易になります。
Systemdタイマーユニットの構造を理解する
Systemdタイマーユニットは、常にアクティブ化することを目的とした対応するサービスユニット(または別のユニットタイプ)とペアになっています。タイマーユニット自体は、関連するユニットがいつアクティブ化されるべきかを定義し、サービスユニットはどのようなアクションを実行するかを定義します。両方のユニットは通常、同じディレクトリ、カスタムユニットの場合は多くの場合/etc/systemd/system/に配置されます。
一般的なタイマーユニットファイルは.timer拡張子を持ち、それに関連するサービスユニットファイルは.service拡張子を持ちます。たとえば、mytask.serviceで定義されたタスクをスケジュールしたい場合は、mytask.timerファイルを作成します。
例:mytask.timerの構造
[Unit]
Description=Run my custom task daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
主要なセクションを見ていきましょう:
-
[Unit]セクション:Description:タイマーの人間が読める説明です。これはステータス出力での識別に役立ちます。
-
[Timer]セクション:これはタイマーユニットの中核であり、スケジューリングを定義します。OnCalendar=daily:このディレクティブは、タイマーがいつアクティブ化されるべきかを指定します。dailyは*-*-* 00:00:00の短縮形です。Systemdは、cronに似ていますが、より柔軟な幅広いカレンダーイベント仕様をサポートしています。その他の例は次のとおりです。hourly:毎時。weekly:毎週(Mon *-*-* 00:00:00と同等)。Sun *-*-* 10:00:毎週日曜日の午前10時。*-*-15 14:30:毎月15日の午後2時30分。Mon..Fri *-*-* 09:00:平日の午前9時。
Persistent=true:これがtrueに設定されている場合、システムがオフになっている間にイベントが発生した場合、タイマーは可能な限りすぐにアクティブ化されます。OnCalendarタイマーの場合、これは、スケジュールされた時間にシステムがオフになっていた場合、システムが起動しタイマーがアクティブになったときに一度トリガーされることを意味します。OnBootSec=:システム起動後、指定された時間が経過した後にタイマーをアクティブ化します。たとえば、OnBootSec=15minは起動から15分後にトリガーされます。OnUnitActiveSec=:タイマーがアクティブ化するユニット(例:サービス)が最後にアクティブになってから指定された時間が経過した後にタイマーをアクティブ化します。たとえば、OnUnitActiveSec=1hは、関連するサービスが最後に終了してから1時間後にトリガーされます。OnUnitInactiveSec=:タイマーがアクティブ化するユニットが最後に非アクティブになってから指定された時間が経過した後にタイマーをアクティブ化します。AccuracySec=:タイマーの精度を指定します。Systemdは、イベントがこの時間枠内にある場合にのみタイマーのためにシステムをウェイクアップしようとし、電力の節約に役立ちます。デフォルトは1minです。RandomizedDelaySec=:指定された期間まで、タイマートリガーにランダムな遅延を追加します。負荷分散に役立ちます。
-
[Install]セクション:このセクションは、タイマーユニットをどのように有効にできるかを定義します。WantedBy=timers.target:このディレクティブは、タイマーが有効になったときに、すべてのアクティブなタイマーを含む標準ターゲットであるtimers.targetの一部になることを保証します。これは、タイマーが有効になると、起動時に自動的に開始されることを意味します。
例:mytask.serviceの構造
[Unit]
Description=My custom task service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/my_custom_script.sh
User=myuser
Group=mygroup
[Install]
WantedBy=multi-user.target
-
[Unit]セクション:Description:サービスの説明。
-
[Service]セクション:これはサービス自体を定義します。Type=oneshot:一度実行してから終了するタスクに適しています。長時間実行されるデーモンには他のタイプが存在します。ExecStart:実行するコマンド。スクリプトに実行権限があることを確認してください。User/Group:コマンドを実行するユーザーとグループを指定します。絶対に必要な場合を除き、rootとしてタスクを実行しないのが良い習慣です。
-
[Install]セクション:このセクションは通常、起動時に開始されるべきサービスに存在しますが、タイマーによってのみ開始されることを意図しているサービスの場合、これは厳密には必要ないかもしれません。
タイマーユニットの作成と有効化
Systemdタイマーユニットを作成および管理するには、以下の手順に従ってください。
-
サービスユニットファイルの作成:タスクを
.serviceファイルで定義します。これを/etc/systemd/system/(ユーザー固有のタイマーの場合は~/.config/systemd/user/)に配置します。
bash sudo nano /etc/systemd/system/mytask.service
上記のサービス例の内容を貼り付けて保存します。 -
タイマーユニットファイルの作成:対応する
.timerファイルでスケジュールを定義します。サービスファイルと同じディレクトリに配置します。
bash sudo nano /etc/systemd/system/mytask.timer
上記のタイマー例の内容を貼り付けて保存します。 -
Systemdデーモンのリロード:ユニットファイルを作成または変更した後、Systemdにその設定をリロードするように指示する必要があります。
bash sudo systemctl daemon-reload -
タイマーの有効化:タイマーが起動時に自動的に開始されるようにするには、それを有効にします。
bash sudo systemctl enable mytask.timer
注:タイマーによってのみトリガーされることを意図している場合、サービスファイルを有効にする必要はありません。 -
タイマーの開始:タイマーを直ちに開始します。その後、スケジュールに従って実行されます。
bash sudo systemctl start mytask.timer
タイマーユニットの管理と監視
Systemdは、タイマーを管理および監視するためのいくつかのsystemctlコマンドを提供しています。
-
すべてのタイマーを一覧表示:すべてのアクティブおよび非アクティブなタイマーを確認します。
bash systemctl list-timers
このコマンドは次のような出力を提供します。
NEXT LEFT LAST PASSED UNIT ACTIVATES Tue 2023-10-27 08:00:00 UTC 10h left Wed 2023-10-26 08:00:00 UTC 14h ago mytask.timer mytask.service
これは、タイマーが次に実行される予定時刻、実行までの残り時間、最後に実行された時刻、およびアクティブ化するサービスを示します。 -
特定のユニットのタイマーを一覧表示:特定のサービスに関連するタイマーを確認したい場合。
bash systemctl list-timers --all | grep mytask.service -
タイマーステータスの確認:特定のタイマーに関する詳細情報を取得します。
bash systemctl status mytask.timer
これにより、タイマーがアクティブであるかどうか、次にいつ実行される予定か、および最近のログエントリが表示されます。 -
サービスログの表示:タイマーによって実行されたタスクの出力とステータスを確認するには、関連するサービスのログを確認します。
bash journalctl -u mytask.service
リアルタイムでログを追跡することもできます。
bash journalctl -f -u mytask.service -
タイマーの停止:タイマーを一時的に無効にする必要がある場合。
bash sudo systemctl stop mytask.timer -
タイマーの無効化:タイマーが起動時に開始されるのを防ぎ、実行中の場合は停止させます。
bash sudo systemctl disable mytask.timer
高度なタイマー設定
特定の間隔の設定
dailyやhourlyの代わりに、より正確な間隔を定義できます。
- N分ごと:
OnUnitActiveSec=15min(サービスが前回終了してから15分後に実行)。 - 特定の時刻:
OnCalendar=*-*-* 02:30:00(毎日午前2時30分に実行)。 - 条件の組み合わせ:
OnCalendar=Mon..Fri *-*-* 08:00:00(平日午前8時に実行)。
省電力のためのAccuracySecの使用
タスクが正確な瞬間に実行される必要がない場合は、AccuracySecの使用を検討してください。たとえば、AccuracySec=5minは、スケジュールされた時刻から5分以内にシステムをウェイクアップしても問題ないことをSystemdに伝えます。これにより、Systemdはタイマーイベントを束ねることができ、システムをより長い期間低電力状態に保つことができる可能性があります。
[Timer]
OnCalendar=hourly
AccuracySec=5min
Persistent vs. WakeUpOn
Persistent=trueは、システムがオフになっているためにOnCalendarイベントがスキップされた場合、次回の起動時に一度実行されることを保証します。これは、スキップしてはならないタスクにとって重要です。WakeUpOn=(例:WakeUpOn=battery、WakeUpOn=ac)は、タイマーのためにシステムがウェイクアップすべき条件を指定するために使用できます。これはより高度な機能であり、多くの場合systemd-suspend.serviceと組み合わせて使用されます。
タイマーとCronの比較
| 機能 | Systemdタイマー | Cron |
|---|---|---|
| 統合 | Systemdサービス、ターゲットとの深い統合 | スタンドアロンのユーティリティ |
| スケジューリング | 柔軟(カレンダー、相対時間、起動ベース) | 主に時刻ベースの表現 |
| ロギング | journalctlを介した一元化 |
分散している(/var/log/syslog、/var/log/cron.log) |
| エラー処理 | サービス障害にアクションを関連付け可能 | 基本的なメール通知 |
| 依存関係 | 他のアクティブなサービスに依存可能 | 限定的 |
| 実行 | 特定のユーザー、グループとして実行可能 | crontabを介して特定のユーザーとして実行可能 |
| 電力管理 | 省電力のために最適化可能(AccuracySec) |
直接的な制御が少ない |
Systemdタイマーを選択すべきとき:
- 他のSystemdサービスとのより緊密な統合が必要な場合。
- 一元化されたロギングと容易なデバッグが優先事項である場合。
- より高度なスケジューリングオプション(例:前回実行からの経過時間)が必要な場合。
- システムの状態または電力管理に関連するタスクの場合。
Cronが依然として推奨される可能性があるとき:
- Systemdを完全に採用していないシステムでの、非常に単純なスタンドアロンタスクの場合。
- さまざまなLinuxディストリビューションおよび古いシステム間での最大限の互換性を求める場合。
一般的な問題のトラブルシューティング
- タスクが実行されない場合:
- タイマーのステータスを確認する:
systemctl status mytask.timer。「Active: active」および「Triggered...」メッセージを探します。 - サービスログを確認する:
journalctl -u mytask.service。スクリプトが実行可能であり、エラーがないことを確認してください。 OnCalendarの構文を確認する:systemd-analyze calendar 'your-calendar-string'を使用してテストします。- タイマーが有効になっており、開始されていることを確認する:
systemctl list-timers --all。
- タイマーのステータスを確認する:
- タスクの実行が早すぎる/遅すぎる場合:
AccuracySecとRandomizedDelaySecを確認します。- システムクロックが正確であることを確認する(
timedatectl status)。
- 権限エラー:
.serviceファイルで指定されたUserとGroupが、スクリプトおよびアクセスするファイルに必要な権限を持っていることを確認します。- ユーザーが指定されていない場合、デフォルトはrootになります。root権限には注意してください。
まとめ
Systemdタイマーユニットは、Linuxシステムでのタスクスケジューリングに対する堅牢でモダンなアプローチを提供します。それらの構造、作成、および管理を理解することにより、日常的な操作を効果的に自動化し、システムの信頼性を向上させ、Systemdエコシステムの全機能を活用することができます。変更後には必ずデーモンをリロードし、永続化のためにタイマーを有効にし、効率的な監視とトラブルシューティングのためにjournalctlを利用することを忘れないでください。