Systemdタイマー入門:信頼性の高いスケジューリングのためのCronジョブの置き換え
数十年にわたり、cronはLinuxおよびUnixライクなシステムでタスクをスケジューリングするための事実上の標準でした。そのシンプルさと遍在性により、管理者にとっても開発者にとっても不可欠なツールとなってきました。しかし、Linuxシステムが進化するにつれて、特にシステムおよびサービスマネージャーとしてのsystemdの登場により、より堅牢で統合されたスケジューリングメカニズムが利用可能になりました。systemdタイマーユニット(.timerファイル)は、従来のcronジョブに代わる、モダンで強力、そして多くの場合に優れた代替手段を提供します。
このガイドでは、systemdタイマーの利点を探り、それらがsystemdエコシステムの他の部分とどのようにシームレスに統合されるかを詳しく説明します。タイマー(.timer)ファイルとサービス(.service)ファイルの両方を設定するための包括的なウォークスルーを提供し、堅牢で再現性があり、容易に管理可能なスケジューリングタスクを作成できるようにします。この記事の終わりまでに、なぜsystemdタイマーが最新のLinux環境で信頼性の高いタスクスケジューリングの好ましい選択肢となるのかを理解するでしょう。
Systemdタイマーの理解
systemdタイマーは、他のsystemdユニット、通常はserviceユニットがいつアクティブ化されるかを制御するsystemdユニットファイルです。スタンドアロンのデーモンであるcronとは異なり、systemdタイマーはsystemdinitシステムの不可欠な一部です。この深い統合は、特に信頼性、ロギング、リソース管理に関して、いくつかの重要な利点をもたらします。
A systemdタイマーは、常に別のユニット、最も一般的にはserviceユニットと連携して機能します。.timerファイルはイベントがいつ発生するかを定義し、対応する.serviceファイルは、そのイベントがトリガーされたときにどのようなアクションが実行されるかを定義します。この懸念事項の明確な分離により、systemdタイマーは高度にモジュール化され、柔軟になります。
Cronに対するSystemdタイマーの主な利点
cronは機能しますが、systemdタイマーは、その多くの制限に対処し、より堅牢で機能豊富なスケジューリングソリューションを提供します。
- 信頼性と永続性:
systemdタイマーがPersistent=trueで設定されており、スケジュールされた実行中にシステムが電源オフになった場合、関連付けられたサービスはシステムが再び起動した後、すぐに実行されます。一方、cronジョブは、システムがダウンしている場合、スケジュールされた実行を見逃すだけです。 systemdとの統合: タイマーは、systemdの強力なロギング(journalctl経由)、依存関係管理、リソース制御(cgroups)の恩恵を受けます。これは、監視の改善、エラー報告の明確化、およびスケジューリングタスクのための複雑な起動シーケンスやリソース制限を定義する機能につながります。- 再現性とバージョン管理:
systemdユニットファイルはプレーンテキストファイルであり、バージョン管理システムに容易に保存できます。これにより、複数のシステム間でのスケジューリングタスクの変更の追跡が容易になり、デプロイメントの再現性が可能になります。 - イベントベースのスケジューリング: 単純な時間ベースのスケジューリングに加えて、
systemdタイマーはシステム起動からの相対時間(OnBootSec)や、ユニットの最後の起動からの時間(OnUnitActiveSec)に基づいてトリガーでき、より動的なスケジューリングオプションを提供します。 - 柔軟な時間表現:
systemdは、cronの構文よりも読みやすく多用途なことが多いカレンダーイベント表現の豊富なセットを提供します。これには、時間ごと、日ごと、週ごと、および特定の年月日/時刻が含まれます。 - リソース管理と依存関係: タイマーによって起動された
systemdサービスは、cgroup設定を含むsystemd環境を継承し、他のsystemdユニットへの依存関係を宣言できます(例:実行前にネットワークやデータベースが利用可能になるのを待つ)。 - 標準出力/エラー処理:
systemdは、タイマーによって起動されたサービスのstdoutとstderrを自動的にキャプチャし、システムジャーナルにリダイレクトします。これにより、cronのメールベースの出力や手動リダイレクトよりもデバッグと監査がはるかに容易になります。
Systemdタイマーの設定
systemdタイマーを設定するには、2つのユニットファイル、すなわちサービスユニット(.service)とタイマーユニット(.timer)を作成する必要があります。これらのファイルは通常、システム全体のタイマーの場合は/etc/systemd/system/に、ユーザー固有のタイマーの場合は~/.config/systemd/user/に配置されます。
1. サービスユニット(.serviceファイル)
サービスユニットは、実際に実行されるコマンドまたはスクリプトを定義します。これは標準のsystemdサービスファイルですが、多くの場合、非対話的に実行され、特定のタスクを実行するように設計されています。
例: /etc/systemd/system/mytask.service
[Unit]
Description=My Scheduled Task Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mytask.sh
User=myuser
Group=mygroup
# Optional: Limit resources
# CPUShares=512
# MemoryLimit=1G
[Install]
WantedBy=multi-user.target
説明:
[Unit]: ユニットに関する一般的な情報を含みます。Description: 人間が読める説明。
[Service]: サービス固有の設定を定義します。Type=oneshot: サービスが単一のコマンドを実行し、その後終了することを示します。これはスケジューリングタスクで一般的です。ExecStart: 実行されるコマンドまたはスクリプト。完全なパスを指定してください。User,Group: コマンドが実行されるユーザーとグループを定義します。タスクは常に、必要最小限の権限で実行してください。CPUShares,MemoryLimit: (オプション)systemdを使用すると、cgroupを活用してサービスのリソース制限を設定できます。
[Install]: ユニットがどのように有効化されるかを定義します。WantedBy=multi-user.target: 存在しますが、タイマーユニット自体が通常アクティベーションを決定するため、タイマーによってトリガーされるサービスにとっては、このセクションはそれほど重要ではないことがよくあります。ただし、サービスを手動でアクティブ化できるようにしたい場合や、他のsystemdターゲットとの統合を望む場合には役立ちます。
2. タイマーユニット(.timerファイル)
タイマーユニットは、対応するサービスユニットがいつアクティブ化されるかを定義します。サービスコンポーネントと同じ名前を持っている必要があります(例: mytask.serviceに対してmytask.timer)。
例: /etc/systemd/system/mytask.timer
[Unit]
Description=Runs mytask.service daily
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=600
AccuracySec=1min
[Install]
WantedBy=timers.target
説明:
[Unit]: 一般情報。Description: タイマーの説明。
[Timer]: タイマー固有の設定を定義します。OnCalendar: 最も一般的な設定で、カレンダーイベントを定義します。次のような式を使用します。daily: 毎日午前0時。weekly: 毎週月曜日の午前0時。monthly: 毎月1日の午前0時。hourly: 毎時0分。*-*-* 03:00:00: 毎日午前3時。Mon..Fri 08:00..17:00: 平日の午前8時から午後5時まで。Mon *-*-* 03:00:00: 毎週月曜日の午前3時。
OnBootSec: システム起動から指定された時間後にサービスをアクティブ化します。例:OnBootSec=10min。OnUnitActiveSec: サービスの前回の起動から指定された時間後にサービスをアクティブ化します。例: 実行完了後1時間ごとに実行するにはOnUnitActiveSec=1h。Persistent=true: 信頼性にとって重要です。スケジュールされた実行中にシステムがオフの場合、サービスは次回の起動後すぐにトリガーされます。RandomizedDelaySec=600: スケジュールされた時刻にランダムな遅延(最大600秒)を追加します。意図しない「