お仕事にて、Linuxのサービス管理とSystemdの話が出てきたので、Systemdについて勉強してみます。
目次
2.systemdによる管理のしくみ( ユニット / ユニットの種別 )
1.systemdとは
systemdは、OSのシステムやサービスなどの管理機能であり、RedHat7以降では標準で利用されている。
(使ったことはないけど、RedHat6以前はinit/Upstartというしくみが使われていたらしい。)
システムやら管理機能やらと言われても自分がピンと来ないので、もう少し平易に言い換えると、
systemdとは、OS自体や、OSにインストールした各種ソフトウェアなどを動かしてくれるもの。
systemdがいるから、OSを動かすために必要な機能や、インストールしたソフトウェアなどを起動することができるようになっている。
2.systemdによる管理のしくみ
ここから、systemdの管理機能の仕組みを見ていく。
◎ユニット
systemdでは、ユニットと呼ばれる単位でサービスなどを管理しており、ユニット毎にユニットファイル(設定ファイル)を定義する必要がある。
基本的に、systemdのユニットファイルは以下に配置される。
配置先 | 説明 | 優先度 |
---|---|---|
/etc/systemd/system/ | systemctl enableコマンド(後述) で作成されたユニットファイルや、追加されたユニットファイル。 (明示的に作られたファイル。) |
A |
/run/systemd/system/ | ランタイム時に作成されたユニットファイルの格納先。 | B |
/usr/lib/systemd/system/ | インストール済みの RPM パッケージで配布された ユニットファイルの格納先。 ソフトウェアパッケージの開発元がユニットファイルを 作っていた場合、当該ファイルはパッケージインストール時に 自動展開される。その展開先がこのディレクトリとなる。 |
C |
ユニット同士には依存関係があり、default.targetというユニットを頂点とした階層構造がとられている。
default.targetは、上記表の中の、/etc/systemd/system配下にユニットファイルが配置されており、
システム(OS)が起動すると、default.targetがまず読み込まれ、起動することになる。
default.targetには、次に起動するユニットなどの情報が記載されており、その情報に従って、ユニットが起動する。
起動したユニットは、さらに自身のユニットファイル内に定義された次のユニットを起動させ、次のユニットはさらに次のユニットを…、というように、各ユニットが階層的に起動していく。
◎ユニットの種別
systemdで管理されるユニットには、以下の種別がある。
ユニット種別 | 説明 | 拡張子 |
---|---|---|
サービス | デーモンやプロセス | .service |
ターゲット | 複数のユニットを1のグループにまとめた単位 | .target |
自動マウント | ファイルシステムの自動マウントポイント | .automount |
デバイス | カーネルが認識するデバイスファイル | .device |
マウント | ファイルシステムのマウントポイント | .mount |
パス | ファイルシステム内のファイルまたはディレクトリ | .path |
スコープ | 外部作成のプロセス | .scope |
スライス | システムプロセスを管理する、階層的に構成されたユニットのグループ | .slice |
スナップショット | systemd マネージャーの保存状態。 | .snapshot |
ソケット | プロセス間の通信ソケット。 システムのローカル IPC やネットワークソケットをカプセル化して、 ソケットベースのアクティベーションを可能とする。 |
.socket |
スワップ | スワップデバイスまたはスワップファイル | .swap |
タイマー |
systemd タイマー |
.timer |
3.ユニットファイルを見てみる
ここで、ユニットファイルの1つを見てみる。
ユニットには様々な種類があると前述したが、そのうち代表格であるサービスタイプの設定を見ていきたい。
サンプルとして、/usr/lib/systemd/system/NetworkManager.serviceの中身を確認。(コメント部分は省略)
[Unit]
Description=Network Manager
Documentation=man:NetworkManager(8)
Wants=network.target
After=network-pre.target dbus.service
Before=network.target network.service
[Service]
Type=dbus
BusName=org.freedesktop.NetworkManager
ExecReload=/usr/bin/busctl call org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Reload u 0
#ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/sbin/NetworkManager --no-daemon
Restart=on-failure
# NM doesn't want systemd to kill its children for it
KillMode=process
CapabilityBoundingSet=CAP_NET_ADMIN CAP_DAC_OVERRIDE CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_MODULE CAP_AUDIT_WRITE CAP_KILL CAP_SYS_CHROOT
ProtectSystem=true
ProtectHome=read-only
[Install]
WantedBy=multi-user.target
Also=NetworkManager-dispatcher.service
この例のように、サービスの定義ファイルは、Unitセクション、Serviceセクション、Installセクションの3つに分かれている。(場合によってInstallセクションがないときもある)
また各セクションには、Key=Valueの形式でパラメータが設定されている。
各パラメータの詳細はmanページ参照。
セクションの意味は以下の通り。
セクション | 説明 |
---|---|
Unit | ユニット種別に関係なく、どのユニットであっても 設定できるオプションは、このセクションに記述する。 |
Service | Serviceユニット特有で 設定できるパラメータは、このセクションに記述する。 |
Install | ユニットの起動有効化時に行う設定パラメータは、 このセクションに記述する。 |
systemdの起動制御は、これら定義ファイルをもとに行われる。
通常、これらサービスファイルは、サービスの提供元(開発元)が作成し、サービスインストール時に展開されていることが多い。
そのため、基本的にサービスファイルの作成や修正の必要はないが、開発元がファイルを作成していない場合や、何かの理由で設定変更が生じた場合は、作成・修正も可能である。
4.systemctlコマンド
systemdの各ユニットの起動等の制御は、systemctlコマンドで行う。
「3.ユニットファイルを見てみる」で示したユニットファイルが、起動時の方法(仮に起動するとしたとき、どのような状態で起動するか)を設定するものとすれば、
systemctlコマンドでの設定は、そもそも起動させるのかどうかといった、より大本の部分を指定するという使い分けとなる。
systemctlコマンドでできる主なことは、以下の通り。
・管理下にあるユニットの一覧表示。
$ systemctl list-units
・指定ユニットの状態表示。(有効であるかどうか等)
$ systemctl status ユニットの名称
例: ※以下の場合、NetworkManagerのサービスがきちんと読み込まれ、動作していることが分かる。
$ systemctl status NetworkManager.service
● NetworkManager.service - Network Manager
Loaded: loaded (/usr/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-04-02 17:22:51 PDT; 7h ago
Docs: man:NetworkManager(8)
Main PID: 1117 (NetworkManager)
Tasks: 4 (limit: 4852)
Memory: 6.8M
CGroup: /system.slice/NetworkManager.service
tq1117 /usr/sbin/NetworkManager --no-daemon
mq1298 /usr/bin/teamd -o -n -U -D -N -t testteam -c { "runner": { "name": "activebackup" }, "link_watch": { "name": "ethto …(以下略)
・指定ユニットの開始
$ systemctl start ユニット名
・指定ユニットの再起動
$ systemctl restart ユニット名
・指定ユニットの停止
$ systemctl stop ユニット名
・指定ユニットの有効化
※新しくユニットを追加する場合、このコマンドでユニットファイルをSystemdに登録する。
$ systemctl enable ユニット名
・指定ユニットの無効化
$ systemctl disable ユニット名
参考サイト様
・RedHat公式
・Systemd入門(1) - Unitの概念を理解する
https://enakai00.hatenablog.com/entry/20130914/1379146157