🐡

systemdによるスケジューリング

2021/05/02に公開

はじめに

cronやatによる、ジョブスケジューリングについて学んだが、systemdによるジョブスケジューリング方法もあるので、解説する。

systemdによるスケジューリング

systemdによるジョブスケジューリングには、「モノトニックタイマー」と「リアルタイムタイマー」の種類が存在する。

モノトニックタイマー

何らかのイベントから一定時間経過後に実行され、以後定期的に実施されるスケジューリング。

リアルタイムタイマー

cronと同様にカレンダー指定で、定期的に実施するスケジューリング。

基本設定

/etc/systemd/system/配下に、

  • serviceファイル
  • timerファイル
    の2つのファイルを作成する。

serviceファイル

[ec2-user@sandbox system]$ sudo cat testscrpit.service 
[Unit]
Description=Test Script

[Service]
User=ec2-user
Group=ec2-user
Type=oneshot
WorkingDirectory=/home/ec2-user
ExecStart=/home/ec2-user/hello.sh

設定ファイル解説

プロパティ 内容
Unit 各Unitを起動する前後関係などを記述する。descriptionの説明のみここでは記載。
Service サービスの設定。
User コマンドを実行するユーザを指定
Group コマンドを実行するユーザが属するグループを指定
Type サービスプロセスの起動完了を判定する方法を記述。oneshotは一度のみ実行するコマンドに対応
WorkingDirectory 作業ディレクトリ
ExecStart 実行したいコマンドや、shellのパスを記述

timerファイル

[ec2-user@sandbox system]$ sudo cat testscrpit.timer
[Unit]
Description=Test Script Timer

[Timer]
OnCalendar=*:0/5
Persistent=true

[Install]
WantedBy=timers.target

設定ファイル解説

プロパティ 内容
Unit 各Unitを起動する前後関係などを記述する。descriptionの説明のみここでは記載。
Timer タイマーの設定をする
OnCalendar 日時形式で指定する
Persistent Trueの場合は、電源停止などで前回ジョブが未実行だった場合、すぐ実行する
Install systemctl enableで有効化する際に必要になる

設定を反映させる

お馴染みのdaemon-reloadで設定ファイルの再読み込みを実施

[ec2-user@sandbox system]$ sudo systemctl daemon-reload

タイマーを有効化する

[ec2-user@sandbox system]$ sudo systemctl enable testscrpit.timer
Created symlink from /etc/systemd/system/timers.target.wants/testscrpit.timer to /etc/systemd/system/testscrpit.timer.

タイマーを実行させる

[ec2-user@sandbox system]$ sudo systemctl start testscrpit.timer

タイマーが起動していることを確認

[ec2-user@sandbox system]$ sudo systemctl status testscrpit.timer
● testscrpit.timer - Test Script Timer
   Loaded: loaded (/etc/systemd/system/testscrpit.timer; enabled; vendor preset: disabled)
   Active: active (waiting) since 土 2021-05-01 22:45:38 UTC; 1min 17s ago

 5月 01 22:45:38 sandbox systemd[1]: Started Test Script Timer.
 5月 01 22:45:38 sandbox systemd[1]: Starting Test Script Timer.

スケジュール一覧に記載されていることを確認

[ec2-user@sandbox system]$ sudo systemctl list-timers
NEXT                         LEFT          LAST                         PASSED    UNIT                         ACTIVATES
土 2021-05-01 22:50:00 UTC  2min 14s left n/a                          n/a       testscrpit.timer             testscrpit.service
日 2021-05-02 21:59:13 UTC  23h left      土 2021-05-01 21:59:13 UTC  48min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

2 timers listed.
Pass --all to see loaded but inactive timers, too.

ジョブが実行されていることを確認

[ec2-user@sandbox system]$ journalctl -u testscrpit.timer
-- Logs begin at 土 2021-03-06 06:28:00 UTC, end at 土 2021-05-01 22:52:48 UTC. --
 5月 01 22:45:38 sandbox systemd[1]: Started Test Script Timer.
 5月 01 22:45:38 sandbox systemd[1]: Starting Test Script Timer.

systemd-run

タイマーUnitを用いる設定方法よりも簡単にスケジューリングできる方法として、systemd-runコマンドがある。systemd-runコマンドを使用することで、一時的なtimeユニットを作成し、serviceファイルを作成しなくても、特定時刻にジョブが実行されるように設定することが可能になる。

# スケジュールの一覧を確認
[ec2-user@sandbox ~]$ sudo systemctl list-timers
NEXT                         LEFT     LAST                         PASSED   UNIT                         ACTIVATES
日 2021-05-02 21:59:13 UTC  23h left 土 2021-05-01 21:59:13 UTC  6min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.

# 60sごとにuptimeコマンドを実行するジョブをスケジューリングに予約する。
[ec2-user@sandbox ~]$ sudo systemd-run --unit=sandboxtest --on-active=1s --on-unit-active=60s uptime
Running timer as unit sandboxtest.timer.
Will run service as unit sandboxtest.service.

# ジョブがスケジューリングに予約されたことを確認
[ec2-user@sandbox ~]$ sudo systemctl list-timers 
NEXT                         LEFT     LAST                         PASSED    UNIT                         ACTIVATES
土 2021-05-01 22:07:22 UTC  59s left 土 2021-05-01 22:06:22 UTC  266ms ago sandboxtest.timer            sandboxtest.service
日 2021-05-02 21:59:13 UTC  23h left 土 2021-05-01 21:59:13 UTC  7min ago  systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

2 timers listed.
Pass --all to see loaded but inactive timers, too.

# ジョブが実行されていることを確認
[ec2-user@sandbox ~]$ journalctl -u sandboxtest
-- Logs begin at 土 2021-03-06 06:28:00 UTC, end at 土 2021-05-01 22:13:33 UTC. --
 5月 01 22:06:22 sandbox systemd[1]: Started /bin/uptime.
 5月 01 22:06:22 sandbox systemd[1]: Starting /bin/uptime...
 5月 01 22:06:22 sandbox uptime[3598]: 22:06:22 up 22 min,  1 user,  load average: 0.00, 0.00, 0.00
 5月 01 22:07:41 sandbox systemd[1]: Started /bin/uptime.
 5月 01 22:07:41 sandbox systemd[1]: Starting /bin/uptime...

# 登録したジョブスケジューリングを削除
[ec2-user@sandbox ~]$ sudo systemctl stop sandboxtest.timer

# # スケジュールの一覧を確認
[ec2-user@sandbox ~]$ sudo systemctl list-timers 
NEXT                         LEFT     LAST                         PASSED    UNIT                         ACTIVATES
日 2021-05-02 21:59:13 UTC  23h left 土 2021-05-01 21:59:13 UTC  15min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.
[ec2-user@sandbox ~]$ 

Discussion