Linuxでのサービスやデーモンの起動順

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