概要

amazon linux 2023 で定期実行スクリプトを実行させるため systemd timer を使ってみた

背景

  • amazon linux 2 から 2023 へ移行中のEC2インスタンスでcronでとある機能のシェルスクリプトを動かしていた
  • amazon linux 2023 には cron がインストールされていない
    • なぜかコメントのみの /etc/crontab はあった
  • AWS的には systemd timer の使用を推奨している感じ

systemd timer の概要

  • systemd の機能で (機能名).timer というファイル名のユニットファイルを配置しておくことにより定期実行のスケジュール設定ができる
  • 起動したいコマンド/スクリプトなどは (機能名).service というファイル名のファイルに記述する
    • (機能名) は任意の文字列で可
  • timerファイルおよびserviceファイルのファイル名の前半部分は揃える
    • 例 hogehoge.timer および hogehoge.service
  • systemcrl コマンドで起動/自動起動の有効化などを制御する
  • 設定ファイルは /etc/systemd/system へ配置

設定に必要な作業

  • serviceファイルの作成
  • timerファイルの作成
  • 起動
  • 自動起動有効化
  • 確認

serviceファイルの作成

serviceファイルに記述する項目

  • 起動させたいコマンドと付随事項について定義する
    • 説明
    • コマンド名
    • 起動ユーザー
    • 起動ディレクトリ
    • 依存関係など

serviceファイルのフォーマット

  • 下記項目をそれぞれ記述する
    • [Unit]
      • Description=(説明) 説明文を設定。スペースも使用可能
    • [Service]
      • ExecStart=(起動コマンド) 起動させたいコマンドを設定
      • User=(起動ユーザー名) 起動するユーザーを設定
      • WorkingDirectory=(ディレクトリ名) 起動するコマンドの実行ディレクトリを設定

timerファイルの作成

timerファイルに記述する項目

  • 起動スケジュールについて定義する
    • 説明
    • スケジュール

timerファイルのフォーマット

  • 下記項目をそれぞれ記述する
    • [Unit]
      • Description=(説明) 説明文を設定。スペースも使用可能
    • [Timer]
      • OnCalendar=(スケジュール) 定期実行スケジュールを設定
        • cronのフォーマットとは違うので注意
        • 詳しくは man コマンドで man systemd.time.7 でマニュアルを参照のこと
    • [Install]
      • WantedBy=timers.target timers.target のインストールによりタイマー起動の設定を行う

起動

  • systemctl でtimerファイルの起動を行う
    • systemctl start (機能名).timer
    • 起動しても特に結果などは表示されない
  • 下記コマンドでステータス確認をする
    • systemctl status (機能名).timer
    • Active になっていることを確認
# systemctl status timer_test.timer
● timer_test.timer - exec test script
     Loaded: loaded (/etc/systemd/system/timer_test.timer; enabled; preset: disabled)
     Active: active (waiting) since Tue 2023-12-12 06:11:50 UTC; 46min ago
    Trigger: Wed 2023-12-13 06:25:00 UTC; 23h left
   Triggers: ● timer_test.service

Dec 12 06:11:50 ip-172-31-21-23.ap-northeast-1.compute.internal systemd[1]: Started timer_test.timer - exec test script.

自動起動有効化

  • systemctl でtimerファイルの自動起動を有効化する
    • systemctl enable (機能名).timer
    • symlink が作成されたという結果が表示される
[root@ip-172-31-21-23 system]# sudo systemctl enable timer_test.timer
Created symlink /etc/systemd/system/timers.target.wants/timer_test.timer → /etc/systemd/system/timer_test.timer.

確認

  • systemctl list-timers で現在設定されているタイマー設定の一覧が表示される
    • 自分で設定したものが一覧の中(UNITおよびACTIVATESの項目)にあることを確認する
    • 表示項目
      • NEXT 次回起動予定時刻
      • LEFT 次回起動予定時刻までの残り時間
      • LAST 前回起動時刻(設定直後で一度も実行されていない場合は空欄)
      • PASSED 前回実行時刻からの経過時間
      • UNIT timerファイルのファイル名
      • ACTIVATES serviceファイルのファイル名
# systemctl list-timers
NEXT                        LEFT        LAST                        PASSED       UNIT                             ACTIVATES
Tue 2023-12-12 07:10:00 UTC 8min left   Tue 2023-12-12 07:00:02 UTC 1min 40s ago sysstat-collect.timer            sysstat-collect.service
Wed 2023-12-13 00:00:00 UTC 16h left    -                           -            logrotate.timer                  logrotate.service
Wed 2023-12-13 00:07:00 UTC 17h left    -                           -            sysstat-summary.timer            sysstat-summary.service
Wed 2023-12-13 02:31:01 UTC 19h left    -                           -            update-motd.timer                update-motd.service
Wed 2023-12-13 05:30:54 UTC 22h left    Tue 2023-12-12 05:30:54 UTC 1h 30min ago systemd-tmpfiles-clean.timer     systemd-tmpfiles-clean.service
Wed 2023-12-13 06:25:00 UTC 23h left    Tue 2023-12-12 06:25:02 UTC 36min ago    timer_test.timer                 timer_test.service
Mon 2023-12-18 00:06:51 UTC 5 days left -                           -            fstrim.timer                     fstrim.service
-                           -           Tue 2023-12-12 07:01:42 UTC 36ms ago     refresh-policy-routes@enX0.timer refresh-policy-routes@enX0.service

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

サンプルファイル

timerファイル

※毎日 0:00 に定期実行する例

[Unit]
Description=exec test script
After=network.target

[Timer]
OnCalendar=*-*-* 00:00:00

[Install]
WantedBy=timers.target

serviceファイル

※ 下記の要件を実行する例
起動スクリプト /home/ec2-user/test.sh
実行ディレクトリ /home/ex2-user
起動ユーザー ec2-user

[Unit]
Description=exec test script
After=network.target

[Service]
ExecStart=/usr/bin/sh /home/ec2-user/test.sh
User=ec2-user
WorkingDirectory=/home/ec2-user

その他

systemd timer の上記以外の使い方

  • timer ファイルの書き方によっていろいろ制御できます
    • 一回のみ実行 (oneshot)
    • 時間ごとに繰り返し実行 (OnUnitActiveSec)
    • OS起動後一定時間待ってからスケジュール実行を開始 (OnBootSec)

設定ファイルを変更した場合

  • 下記コマンドで反映させる
    • # systemctl daemon-reload
      • コマンド実行後、特になにも表示などはでない

cron一神教の方

どうしても cron が使いたいという人は cronie パッケージをインストールすれば使えます

# dnf list cronie
Last metadata expiration check: 1:52:48 ago on Tue Dec 12 05:16:17 2023.
Available Packages
cronie.x86_64                                                                                1.5.7-1.amzn2023.0.2                                                                                 amazonlinux