blog.monophile.net

コンピュータのこととかのメモ。

山本 一彰 | Takaaki Yamamoto

東京工業大学において計算機科学と応用数学を学び、 情報科学芸術大学院大学[IAMAS]においてメディア表現を専攻し修了。 2015年にコンビネータ論理を基に計算完備な計算手法 "論理珠算"を開発し、 それを含む体系である"算道"を構成した。 その成果により、 第19回 文化庁メディア芸術祭 アート部門 新人賞 (文部科学大臣賞) を2016年に受賞。 現在はインフラエンジニアとして生計をたててている。

技術

各種システムの設計/構築/運用を承ります。

Configuration Management Ansible, Terraform, cloud-init
Cloud Platform AWS, Azure, GCP, Openstack
Openstack Keystone, Glance, Cinder(Ceph), Neutron(VLAN), Nova(QEMU), Horizon
Virtualization QEMU+KVM, LXD/LXC, Docker
OS Ubuntu, Debian GNU/Linux, CentOS, ...
Storage Ceph, GlusterFS, ZFS, btrfs, ...
Networks Tunnel(IPSec, L2TP, VXLAN, GRE), WirelessAP, ...
DB MySQL, MariaDB(Galera Cluster), MongoDB
Mail postfix, dovecot
WebApps WordPress, GitLab, MatterMost, Redmine, RainLoop, ...
Monitoring Nagios, Munin
Misc certbot, dnsmasq, ...

技術(習得中)

Orchestration Kubernetes
Openstack swift, manila, trove
OS CoreOS(Container Linux), Vyatta(VyOS), ...
Networks IPv6, BGP(quagga, calico), flannel, fan, ...
DB/KVS Redis, etcd
Monitoring Prometheus, Zabbix
DNS CoreDNS, PowerDNS
Misc MAAS, Blockchain

投稿

cronの代わりにsystemdのtimerで定期実行を定義してみる

概要

UNIX環境で定期的に処理を実行する場合は一般的にcronを使う。 しかし、cronを使うとログのことに気を遣うのが嫌だった。 (ログの置き場所とか、ログのローテーションとか…。) systemdだとjournaldが一括してログを管理してくれて便利そうだったので、試してみた。 (journaldの設定は /etc/systemd/journald.conf を編集すればよい。)

今回は5秒毎くらいに“hello”を標準出力する処理を実装してみる。 試した環境はUbuntu16.04。

systemd.timer

systemd.timerを使うためには最低2つのファイルが必要になる。 一つは XXXXX.service という処理そのものを定義するファイルで、 もう一つは XXXXX.service をどのタイミングで実行するかを定義する XXXXX.timer というファイル。 XXXXXはserviceとtimerで同じでも異なっていてもいいが、 わかりやすくするために同じの方が良いと思う。 異なっている場合は[Timer]のセクションで明示的にUnit=の指定が必要になる。

マニュアルは↓でみれる。

$ man systemd.timer

わかりやすかったのは↓のwiki。

echo@.service

/lib/systemd/system/echo@.service を↓のように記述する。

[Unit]
Description = echo service

[Service]
Type = oneshot
ExecStart = /bin/echo %i

↑のサービスは↓を実行すると “/bin/echo hoge” が実行される。

$ sudo systemctl start echo@hoge.service

つまり、echo@AAAA.service のAAAAが%iに代入されて実行される。

echo@.timer

上記で定義したサービス echo@.service を2+5n秒毎(誤差2秒)に実行するecho@.timerを定義する。

/lib/systemd/system/echo@.timer を↓のように記述する。

[Unit]
Description = echo@ timer
Wants = multi-user.target
After = multi-user.target

[Timer]
OnCalendar = *-*-* *:*:2/5
RandomizedDelaySec = 2s
Unit = echo@%i.service

[Install]
WantedBy = timers.target

.timer でも .service と同じように@と%iでの置換ができる。

タイマーを起動する

↓で再起動後に自動的に echo@hello.timer が起動するように設定する。

$ sudo systemctl enable echo@hello.timer
Created symlink from /etc/systemd/system/timers.target.wants/echo@hello.timer to /lib/systemd/system/echo@.timer.

↓でecho@hello.timerを起動する。

$ sudo systemctl start echo@hello.timer

するとecho@hello.timerの状態は↓になる。

$ sudo systemctl status echo@hello.timer
● echo@hello.timer - echo@ timer
   Loaded: loaded (/lib/systemd/system/echo@.timer; enabled; vendor preset: enabled)
   Active: active (waiting) since Sat 2018-01-13 20:46:59 JST; 16s ago

Jan 13 20:46:59 timer01 systemd[1]: Started echo@ timer.

↓でだいたい5秒ごとくらいに echo@hello.service が動いていることが確認できる。

$ sudo journalctl -u echo@hello
-- Logs begin at Sat 2018-01-13 20:44:19 JST, end at Sat 2018-01-13 20:48:29 JST. --
Jan 13 20:47:16 timer01 systemd[1]: Starting echo service...
Jan 13 20:47:16 timer01 echo[2198]: hello
Jan 13 20:47:16 timer01 systemd[1]: Started echo service.
Jan 13 20:47:33 timer01 systemd[1]: Starting echo service...
Jan 13 20:47:33 timer01 echo[2213]: hello
Jan 13 20:47:33 timer01 systemd[1]: Started echo service.
Jan 13 20:47:50 timer01 systemd[1]: Starting echo service...
Jan 13 20:47:50 timer01 echo[2214]: hello
Jan 13 20:47:50 timer01 systemd[1]: Started echo service.

(おまけ) 定義されているtimerを確認する

起動したてのUbuntu16.04のtimerの状態は↓で確認できる。

$ systemctl list-timers --all
NEXT                         LEFT          LAST PASSED UNIT                         ACTIVATES
Sat 2018-01-13 18:56:24 JST  10min left    n/a  n/a    systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Sat 2018-01-13 21:27:14 JST  2h 41min left n/a  n/a    snapd.refresh.timer          snapd.refresh.service
Sun 2018-01-14 11:59:07 JST  17h left      n/a  n/a    apt-daily.timer              apt-daily.service
Sun 2018-01-14 15:00:37 JST  20h left      n/a  n/a    apt-daily-upgrade.timer      apt-daily-upgrade.service
n/a                          n/a           n/a  n/a    snapd.snap-repair.timer      snapd.snap-repair.service
n/a                          n/a           n/a  n/a    ureadahead-stop.timer        ureadahead-stop.service

6 timers listed.

(おまけ) サービスの依存関係

systemdはサービスの依存関係を細かく設定できるが、 ユーザレベルで動く処理はmulti-user.targetに依存するように指定しておけば良いと思う。 詳しくは↓を参照。

参考