参考
https://access.redhat.com/ja/articles/1379593
https://www.freedesktop.org/software/systemd/man/systemd.service.html
https://www.freedesktop.org/software/systemd/man/systemd.unit.html
自作スクリプトをsystemdへ登録する(simple)
下記のようなずっと動き続けるようなスクリプトの場合は、simpleで登録する。
- サンプルスクリプト
#!/bin/bash while true; do logger "$(date +%Y/%m/%d-%H:%M:%S) $(basename $0) running" sleep 5 done
-
systemd設定ファイル
[Unit] Description = Sample Script [Service] ExecStart = /usr/local/bin/sample.sh Restart = always Type = simple [Install] WantedBy = multi-user.target
-
systemdの設定反映
# systemctl daemon-reload
-
確認と起動
# systemctl status sample ● sample.service - Sample Script Loaded: loaded (/etc/systemd/system/sample.service; disabled; vendor preset: disabled) Active: inactive (dead) # systemctl start sample # systemctl status sample ● sample.service - Sample Script Loaded: loaded (/etc/systemd/system/sample.service; disabled; vendor preset: disabled) Active: active (running) since Tue 2018-11-06 13:53:06 UTC; 2s ago Main PID: 9239 (sample.sh) CGroup: /system.slice/sample.service ├─9239 /bin/bash /usr/local/bin/sample.sh └─9243 sleep 5 Nov 06 13:53:06 host01.anvils.com systemd[1]: Started Sample Script. Nov 06 13:53:06 host01.anvils.com systemd[1]: Starting Sample Script...
自作スクリプトをsystemdへ登録する(forking)
下記のような起動/停止スクリプトから子プロセスを呼び出すような場合は、forkingを指定する。
- サンプルスクリプト
#!/bin/bash case $1 in start) /usr/local/bin/sample.sh &;; stop) pkill -f "/bin/bash /usr/local/bin/sample.sh";; *) exit 1;; esac
-
systemd設定ファイル
[Unit] Description = Sample Script fork [Service] ExecStart = /usr/local/bin/sample2.sh start ExecStop = /usr/local/bin/sample2.sh stop Restart = always Type = forking [Install] WantedBy = multi-user.target
-
systemdの設定反映
# systemctl daemon-reload
-
確認と起動
# systemctl status sample2 ● sample2.service - Sample Script fork Loaded: loaded (/etc/systemd/system/sample2.service; disabled; vendor preset: disabled) Active: inactive (dead) # systemctl start sample2 # systemctl status sample2 ● sample2.service - Sample Script fork Loaded: loaded (/etc/systemd/system/sample2.service; disabled; vendor preset: disabled) Active: active (running) since Tue 2018-11-06 14:07:15 UTC; 2s ago Process: 9759 ExecStart=/usr/local/bin/sample2.sh start (code=exited, status=0/SUCCESS) Main PID: 9760 (sample.sh) CGroup: /system.slice/sample2.service ├─9760 /bin/bash /usr/local/bin/sample.sh └─9764 sleep 5 Nov 06 14:07:15 host01.anvils.com systemd[1]: Starting Sample Script fork... Nov 06 14:07:15 host01.anvils.com systemd[1]: Started Sample Script fork.
既存設定を追加・変更したい場合
yumでインストールしたnginxなどのsystemd設定を変更したい場合、システム(yumなど)が設定したファイルを直接書き換えるのは、あまりよろしくない。
例えばnginxの場合、下記のファイルを直接書き換えるのはやらない方がいい。
[Unit] Description=The nginx HTTP and reverse proxy server After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid # Nginx will fail to start if /run/nginx.pid already exists but has the wrong # SELinux context. This might happen when running `nginx -t` from the cmdline. # https://bugzilla.redhat.com/show_bug.cgi?id=1268621 ExecStartPre=/usr/bin/rm -f /run/nginx.pid ExecStartPre=/usr/sbin/nginx -t ExecStart=/usr/sbin/nginx ExecReload=/bin/kill -s HUP $MAINPID KillSignal=SIGQUIT TimeoutStopSec=5 KillMode=process PrivateTmp=true [Install] WantedBy=multi-user.target
/etc/systemd/system/{service-name}.service.d
ディレクトリを作成してその配下に追加・上書きする設定を書くといいっぽい。
設定ファイル追加して、 systemctl daemon-reload
systemctl restart nginx
とかすればOK。
[Service] LimitNOFILE=65536
サービス起動順序を指定したい
first-service -> second-serviceの順で起動させたい場合
[Unit] Description = First Service Sample Before = second-service.service [Service] ExecStart = /usr/local/bin/first-service.sh Type = simple [Install] WantedBy = multi-user.target
[Unit] Description = Second Service Sample After = first-service.service Requires = first-service.service [Service] ExecStart = /usr/local/bin/second-service.sh Type = simple [Install] WantedBy = multi-user.target
オプション | 説明 |
---|---|
Before | ユニット開始順序。指定されたユニットより前に開始される。 |
After | ユニット開始順序。指定されたユニットの後に開始される。 |
Requires | 依存関係の設定。指定したユニットも開始する。指定したユニットが正常に開始できない場合、このユニットは開始しない |
ネットワーク起動後にサービス起動したい
ネットワークに接続されてることが前提のサービスの場合、該当サービスのsystemd設定ファイルに下記を追記する。
[Unit] After=network-online.target Wants=network-online.target
オプション | 説明 |
---|---|
After | ユニット開始順序。指定されたユニットの後に開始される。 |
Wants | 依存関係の設定。指定したユニットも開始する。指定したユニットが正常に開始できなくてもこのユニット自体は開始する |
サービス起動順序を確認したい
- 依存関係確認
$ systemctl list-dependencies --all // 全てのユニットの依存関係を表示 $ systemctl list-dependencies first-service --before // first-serviceの後に起動してなければならないユニット $ systemctl list-dependencies first-service --after // first-serviceの前に起動してなければならないユニット $ systemctl list-dependencies first-service --revers // first-serviceに依存してるユニット
-
実際に起動したタイミングと時間を表示
$ systemd-analyze plot > analyzestartup.svg // analyzestartup.svgを適当なブラウザで表示する
停止したら自動で起動し直したい
Restart
で再起動のトリガー指定(基本alwaysでいいと思う)RestartSec
StartLimitInterval
StartLimitBurst
で再起動の間隔、リミットを指定- デフォルトは100ms間隔で再起動を行い、5回失敗でそれ以降は再起動は行われない。
- 下の例だと異常終了して5秒後に自動で再起動を試みる、60秒内で5回失敗したらそれ以降は再起動は行わない。
[Service] Restart = no // 再起動しない Restart = always // 常に再起動する Restart = on-success // exitコード0の場合に再起動する Restart = on-failure // exitコードが0以外の場合に再起動する Restart = on-abnormal // Unclean signal/Timeout/Watchdogの時 Restart = on-abort // Unclean signalの時 Restart = on-watchdog // Watchdogの時 RestartSec = 5 // 異常終了して5秒後に再起動を試みる。デフォルトは100ms StartLimitInterval = 60 // この間隔内にStartLimitBurst回失敗したらそれ以降は何もしない。デフォルトは0でStartLimitBurstのみが有効 StartLimitBurst = 5 // 再起動を試みる回数。手動でサービスリスタートとかすればリセットされる。デフォルトは5
リミットを超えて自動で再起動行われないとmessagesに下記が出力される
systemd: start request repeated too quickly for hoge.service