サーバ構築

systemdへのサービス登録

投稿日:

参考
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 

-サーバ構築
-

Copyright© 明日から頑張ります。 , 2025 All Rights Reserved Powered by STINGER.