Issue
Linuxでサービスの起動停止はsystemctlコマンドを使います。
systemctl enable [サービス名] で自動起動を登録した時に、サービスUnit同士の依存関係に起因するエラーが発生することがあります。
この時、起動順序を制御する方法があります。
Resolution
1.サービスUnitの自動起動の順序を確認する
# systemctl list-dependencies
このコマンドを実行すると、自動起動に登録したサービスUnitの起動順が一覧化されます。
# systemd-analyze plot > unitstart.html
このコマンドを実行すると、実際にサービスUnitがどういう順で起動してどれくらい時間がかかったをHTMLファイルで出力できます。
# systemd-analyze plot > unitstart.html
# firefox unitstart.html
2.サービスUnit同士の依存関係を設定する
依存関係を設定するには、サービスの定義ファイルにパラメータを追加します。
サービスの定義ファイルは、/etc/systemd/system ディレクトリ内にあります。
たとえば、mariadbのサービスファイルは、
[root@testserver ~]# find /etc/systemd/system -name mariadb.service
/etc/systemd/system/multi-user.target.wants/mariadb.service
[root@testserver ~]#
serviceファイルには、 [Unit] というUNIT間の依存関係を設定するディレクティブがあります。
このディレクティブに設定を追加することで、起動時のUnit同士の依存関係を設定できます。
もし、serviceファイルが見つからない場合は、/usr/lib/systemd/systemにインストール時のデフォルト設定のserviceファイルがありますから、そちらを探します。
見つかったserviceファイルを/etc/systemd/systemに配置して設定します。
関係
分類
設定方法と解説
After
前後関係
先行起動するサービスを定義する
■ 「Aよりも前にBを起動する」の定義方法
A.service -------------------------------------------
[Unit]
After=B.service
---------------------------------------------------
”B.serviceより後に自分を起動してください”という設定
Before
前後関係
後続起動するサービスを定義。
■ 「Aの後にBを起動する」の定義方法
A.service -------------------------------------------
[Unit]
Before=B.service
---------------------------------------------------
”A.serviceより後にBserviceを起動してください”という設定
Wants
同時起動依存関係
強制力の無い依存関係。
Systemdはサービスの同時起動を試みるが、依存先の起動に失敗した場合であっても、依存元の起動は引き続き実施する。
■「 AはBに依存する」の定義方法
A.service -------------------------------------------
[Unit]
Wants=B.service
---------------------------------------------------
Requires
同時起動依存関係
強制力のある依存関係。
Systemdはサービスの同時起動を試み、依存先の起動に失敗した場合は、依存元は起動しない。
■「 AはBに依存する」の定義方法
A.service -------------------------------------------
[Unit]
Requires=B.service
---------------------------------------------------
Conflict
同時起動依存関係
競合する関係。
Systemdは関係が定義されたサービスと同時に起動しない。
■「AとBは競合する」の定義方法
A.service -------------------------------------------
[Unit]
Conflicts=B.service
---------------------------------------------------
Troubleshoot
実際に発生した自動起動時の依存関係のためにエラーが発生したケースで解決するまでの記録です。
自動起動登録~サービス稼働状態確認まで
snmptrapd.serviceとmariadb.serviceに依存関係があるケースで、以下のように自動起動を登録して、リブートします。
# systemctl enable snmptrapd.service
# systemctl enable mariadb.service
# reboot
起動後にサービスの稼働状態を以下コマンドで確認します。
# systemctl status snmptrapd.service
mariadbに関係するエラーが発生しました。
起動順の前後関係で問題が発生していることの確認まで
mariadbのサービス稼働状態を確認してみると、正常に稼働していました。
# systemctl status mariadb.service
snmptrapd.serviceを再起動してみると、正常起動しています。
# systemctl restart snmptrapd.service
# systemctl status snmptrapd.service
このことから、起動順の前後関係が解決すれば、snmptrapd.serviceが正常稼働できることがわかりました。
実際の起動順をグラフ化してみると、snmptrapd.serviceがmariadb.service起動前に始まり、mariadb.serviceが起動完了前に実行完了していることがわかります。
# systemd-analyze plot > unitstart.html
# firefox unitstart.html
起動前後関係設定~解決まで
snmptrapd.serviceをmariadb.service起動完了後にはじまるように設定します。
# vi /etc/systemd/system/multi-user.target.wants/snmptrapd.service
Unitディレクティブに
After=mariadb.service
を追記します。
マシンを再起動してみると、前回起動時にはエラーであったsnmptrapd.serviceが正常に稼働したことがわかります。
# systemctl status snmptrapd.service
実際の起動順を確認してみると、mariadb.serviceが稼働後にsnmptrapd.serviceが起動されたことがわかります。
# systemd-analyze plot > unitstart2.html
# firefox unitstart2.html