【基礎】RedHatのSystemdを学ぶ | 若手エンジニアのブログ

若手エンジニアのブログ

文系出身の若手女子エンジニアによる技術ブログ。
日々の経験や学びをアウトプットするためにブログを書いています。
バックエンド(Java+SpringFramework)を経てインフラエンジニアになりました。
今は育休中につき、本で勉強したことを中心にアウトプットしています。

お仕事にて、Linuxのサービス管理とSystemdの話が出てきたので、Systemdについて勉強してみます。

 

目次

1.systemdとは

2.systemdによる管理のしくみ( ユニット / ユニットの種別 )

3.サービス定義ファイルを見てみる

4.systemctlコマンドで制御

参考サイト様

 

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の概念を理解する