Systemdのユニットファイルのカスタマイズ
Systemdは、RHEL7、CentOS7以降における基本的なサービス管理機能 (等を含むシステム管理デーモンやツールの一式) です。従来はUpstart、SysVinitがありました。
本記事では、サービス起動時のオプション変更等、Systemdのユニットファイルをカスタマイズする際のポイントをまとめます。
Systemdに関する基本的な内容は、以下の記事にまとめてあります。
主な2つのカスタマイズ方法
サービス起動時のオプション変更等、Systemdのユニットファイルをカスタマイズする場合、主に以下2つの方法があります。
-
ユニットファイルをまるごと新たに作成
-
カスタマイズしたい設定のみを記載したドロップインスニペット (drop-in file) を作成
本記事では、これらの方法について説明します。
カスタマイズの前提
前提とする環境や条件について記載します。
カスタマイズ対象のユニットファイルはパッケージ標準のものを想定
カスタマイズ対象のユニットファイルは、OS標準のRPM等にデフォルトで含まれるものを想定します。
基本的に /usr/lib/systemd/system/
配下に格納されているはずです。
ユニットファイルに関する主なパス
ユニットファイルの主な格納パスは以下です。
/usr/lib/systemd/system/
:パッケージマネージャによって配置/etc/systemd/system/
:システム管理者によって配置
前者が、RPM等にデフォルトで含まれるユニットファイルが格納されるパスです。後者は、システム管理者が個別にユニットファイルを用意して格納するためのパスです。
同名のユニットファイルが /usr/lib/systemd/system/
と /etc/systemd/system/
の両方に配置された場合、/etc/systemd/system
内のファイルが優先されます。
詳細は、 man systemd.unit
の “UNIT FILE LOAD PATH” セクションや、開発元のドキュメントに記載があります。
注意:デフォルトのユニットファイルを直接変更しない
RPM等のパッケージにデフォルトで含まれるユニットファイルを変更しない方が良いという点についても記載しておきます。
具体的には、カスタマイズのために /usr/lib/systemd/system/
配下のユニットファイルを直接変更しないということです。
理由は、デフォルトのユニットファイルに対する変更が含まれるようなパッケージの修正を適用する際、/usr/lib/systemd/system/
配下のユニットファイルが、新しいデフォルトのユニットファイルによって上書きされる場合があるためです。
この場合、/usr/lib/systemd/system/
配下のユニットファイルをカスタマイズのため変更済みだったとすると、上書きによって変更内容が失われてしまいます。ユニットファイルが意図せず変更前の状態に戻ってしまうと、トラブル等が発生する可能性もあります。
本記事では、そのような状況を回避できるカスタマイズ方法について説明します。
方法1:ユニットファイルをまるごと新たに作成
/usr/lib/systemd/system/
配下のユニットファイルを /etc/systemd/system/
配下にいったんコピーし、コピーしたユニットファイルを編集する方法です。
この方法のメリットは、パッケージにデフォルトで含まれる /usr/lib/systemd/system/
配下のユニットファイルが読み込まれなくなるので、ユニットファイルをまるごと置き換えられるという点です。
逆に、パッケージのアップデート時、デフォルトで含まれるユニットファイルに対する修正があった際、それを自動的には適用できなくなる点がデメリットです。
ユニットファイルの作成手順等
/etc/systemd/system/
配下へのユニットファイルの配置については、RHEL8のマニュアル の記載が分かりやすいかと思います。
作成後、systemctl daemon-reload
でユニットファイルを読み込ませる必要性があります。
また、現在使用されているユニットファイルは、 systemctl status
の結果にLoaded:
行が表示されることでも確認できます。
$ systemctl status httpd
● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
サービスの再有効化が必要なケース
既に自動起動が有効(enable)なサービスに対して、この方法でユニットファイルをカスタマイズした場合には、以下のようにサービスの無効化→有効化のやり直しが必要です。
# systemctl disable httpd.service # systemctl enable httpd.service
これは、/usr/lib/systemd/system/
配下のユニットファイルに対して既にシンボリックリンクが作成されていたサービスについて、新たに配置した /etc/systemd/system
配下のユニットファイルに対してシンボリックリンクを作成し直すための操作です。
サービスの再起動が必要なケース
上記と同様の理由で、既に自動起動が有効(enable)なサービスに対して、この方法でユニットファイルをカスタマイズした場合には、カスタマイズしたユニットファイルを使用してサービスを起動させるため、必要に応じサービスを再起動しましょう。
方法2:カスタマイズしたい設定のみを記載したドロップインスニペット (drop-in file) を作成
/etc/systemd/system/(ユニット名).d
配下に、(任意の名前).conf
を作成する方法です。このように作成したファイルのことを、ドロップインスニペット (drop-in file) と呼びます。
この方法のメリットは、必要な箇所の設定のみを変更 (上書き) できる点と、パッケージのアップデート時、デフォルトで含まれるユニットファイルに対する修正があった際、それを自動的に適用できる点です。
逆に、変更 (上書き) した設定箇所と、パッケージの修正内容との間に非互換が発生し得る点がデメリットです。
ドロップインスニペットの作成や管理の手順
なお、特に理由が無ければ、ドロップインスニペットはファイルを直接作成せず、systemctl edit
コマンドを使用するよう統一して運用するのが良い気がします。
具体的な手順については、以下の記事にまとめてあります。
パラメタによって、"クリア" の方法が異なる
リストとして読み込まれる設定を削除したい場合には、上書きせず、まずクリアしてから設定を追加する必要性があります。
以下のような方法です。
AssertPathExists=
AssertPathExists=/srv/www
…
Note that for drop-in files, if one wants to remove entries from a setting that is parsed as a list (and is not a dependency), such as AssertPathExists= (or e.g. ExecStart= in service units), one needs to first clear the list before re-adding all entries except the one that is to be removed. Dependencies (After=, etc.) cannot be reset to an empty list, so dependencies can only be added in drop-ins. If you want to remove dependencies, you have to override the entire unit.
出典:freedesktop.org
上記には、After等はドロップインスニペットでクリアすることができない旨も記載されています。
ドロップインスニペットは辞書順 (alphanumeric order) に読み込まれる
以下、引用です。
Along with a unit file foo.service, a “drop-in” directory foo.service.d/ may exist. All files with the suffix “.conf” from this directory will be merged in the alphanumeric order and parsed after the main unit file itself has been parsed. This is useful to alter or add configuration settings for a unit, without having to modify unit files.
出典:freedesktop.org
ドロップインスニペットは、/etc/systemd/system以外に、/usr/libや/run配下にも格納できる
優先度が高い順に、/etc/systemd/system、/run、/usr/libとなるようです。
以下、引用です。
In addition to /etc/systemd/system, the drop-in “.d/” directories for system services can be placed in /usr/lib/systemd/system or /run/systemd/system directories. Drop-in files in /etc/ take precedence over those in /run/ which in turn take precedence over those in /usr/lib/. Drop-in files under any of these directories take precedence over unit files wherever located. Multiple drop-in files with different names are applied in lexicographic order, regardless of which of the directories they reside in.
出典:freedesktop.org
関連ドキュメント
詳細は、開発元のドキュメントを参照ください。
httpd.serviceのカスタマイズ例も記載されています。
該当箇所を引用しておきます。
There are two methods of overriding vendor settings in unit files: copying the unit file from /usr/lib/systemd/system to /etc/systemd/system and modifying the chosen settings. Alternatively, one can create a directory named unit.d/ within freedesktop.org and place a drop-in file name.conf there that only changes the specific settings one is interested in. Note that multiple such drop-in files are read if present, processed in lexicographic order of their filename.
The advantage of the first method is that one easily overrides the complete unit, the vendor unit is not parsed at all anymore. It has the disadvantage that improvements to the unit file by the vendor are not automatically incorporated on updates.
The advantage of the second method is that one only overrides the settings one specifically wants, where updates to the unit by the vendor automatically apply. This has the disadvantage that some future updates by the vendor might be incompatible with the local changes.
出典:freedesktop.org
まとめ
本記事では、サービス起動時のオプション変更等、Systemdのユニットファイルをカスタマイズする際のポイントをまとめてみました。
参考
開発プロジェクト (アップストリーム)
RHELのマニュアル
-
第12章 systemd の管理 Red Hat Enterprise Linux 9 | Red Hat Customer Portal
-
第14章 systemd の管理 Red Hat Enterprise Linux 8 | Red Hat Customer Portal
-
第10章 systemd によるサービス管理 Red Hat Enterprise Linux 7 | Red Hat Customer Portal