デーモン管理をdaemontoolsからsystemdに移行させる

SREチームの竹田です。Tech Kayac Advent Calendar Migration Track 9日目の記事になります。

カヤック社内では デーモン管理ツールとしてdaemontoolsが愛用されてきました。 ソフトウェアとして枯れており、 自動起動や各シグナルを送ることができるので大変重宝されています。

経緯

AmazonLinux1のEOLに伴い、稼働中のアプリケーションを移行させる必要がでてきました。

最近はコンテナ(ECS)へ移行させる事がほとんどですが、運用やアプリケーションの都合上AmazonLinux2へ移行させる場合もあります。

デーモン管理としてdaemontoolsを利用する事も考えましたが、ドキュメントの整備状況やインストールに難があることもあり、systemdに変更する事にしました。

設定

systemdの詳しい説明は省きますが、 以下のような設定ファイルapp.serviceを用意します。 run.shがデーモンの起動スクリプトです。

[Unit]
Description = WebApp

[Service]
User=app
ExecStart = /home/app/systemd/run.sh
Restart = always
Type = simple
PIDFile=/home/app/systemd/server.pid
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy = multi-user.target

systemdへの登録と起動

シンボリックリンク/etc/systemd/system/app.service を作成します。 daemontoolsの/service/にサービスディレクトリを設置する作業に相当します。

$ sudo  systemctl link /home/app/systemd/app.service

ls -l /etc/systemd/system/app.service
lrwxrwxrwx 1 root root 128 Dec 9 08:00 /etc/systemd/system/app.service -> /home/app/systemd/app.service

$ sudo systemctl daemon-reload

登録状況を確認してみましょう。

$ sudo systemctl list-unit-files --type=service | grep app
app.service                            linked

サービスを有効化します。

$ sudo systemctl enable /home/app/systemd/app.service
Created symlink from /etc/systemd/system/multi-user.target.wants/app.service to /home/app/systemd/app.service

$ sudo systemctl list-unit-files --type=service | grep app
app.service                            enabled

アプリケーションの起動を起動させます。 daemontoolsだとsvc -uにあたるでしょうか。

$ sudo systemctl start app.service

稼働状況を確認してみましょう

$ sudo systemctl status app.service
● app.service - WebApp
   Loaded: loaded (/home/app/systemd/app.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2019-12-05 07:00:00 JST; 3s ago
 Main PID: 22467 (run.sh)
    Tasks: 9
   Memory: 256.8M
   CGroup: /system.slice/app.service
           ├─22467 /bin/sh /home/app/systemd/run.sh
:

稼働を確認することができました。

設定の再読込み

daemontoolsではsvc -hを使う事でプロセスにHUPシグナルを送り設定変更を反映させる事ができました。

systemdではHUPを送る手段が標準では用意されていないので設定ファイルに記述する必要があります。

前述の設定ファイルのExecReloadrelaod時に実行される箇所です。 ここでメインプロセスにHUPシグナルを送るように指定して置くと良いでしょう。

ExecReload=/bin/kill -HUP $MAINPID
$ sudo systemctl reload app.service

これでHUPシグナルを送ることができました。 他にもExecStart, ExecPreStart等のオプションがあるので必要であれば設定を変更してください。

また、 フォークされたプロセスにHUPシグナルを送りたい場合にはPIDFileにPIDファイルパスを渡すことで$MAINPIDを変更することができます。

PIDFile=/home/app/systemd/server.pid

各コマンドの対応

最後にdaemontoolsとsysytemdの主だったコマンドの対応を記載します。

daemontools systemd
svc -u example_app systemctl start example_app
svc -d example_app systemctl stop example_app
svc -t example_app systemctl restart example_app
svc -h example_app systemctl reload example_app
svstat example_app systemctl status example_app