【入門】systemd とは?設定ファイルの書き方や自動起動の設定

systemd

systemd とは、Linux の起動処理 (init) やサービスの管理を行うソフトウェア一式です。

init - カーネルが最初に起動するプロセスで、他の全てのプロセスを起動する役割を持つ

サービス - systemd が起動したプロセスまたはプロセスのグループ。

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/resource_management_guide/sec-default_cgroup_hierarchies
関連記事:Linux の基本機能
スポンサーリンク

systemd の起動処理 (init)

systemd の起動処理 (init) は以下の順で動作します。

  1. systemd プロセス (/usr/lib/systemd/systemd) を開始
  2. /etc/systemd/system/default.target のシンボリックリンクを解決し、ターゲットを確認
  3. ターゲットに対して、依存関係/順序を持つサービスを自動で起動

ターゲット、ランレベルとは

ランレベルとは、昔の Linux の動作モードのことで、起動するサービスが決まります。
systemd を採用した Linux では、「ターゲット」が「ランレベル」に相当する機能です。

ランレベルターゲットユニット詳細
0poweroff.targetシステムをシャットダウンし、電源を切る
1rescue.targetレスキューシェル (シングルユーザーシステム)
2, 3, 4multi-user.target非グラフィカルなマルチユーザーシステム
5graphical.targetグラフィカルなマルチユーザーシステム
6reboot.targetシステムをシャットダウンして再起動
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-targets
ls -l /usr/lib/systemd/system/runlevel?.target
/usr/lib/systemd/system/runlevel0.target -> poweroff.target
/usr/lib/systemd/system/runlevel1.target -> rescue.target
/usr/lib/systemd/system/runlevel2.target -> multi-user.target
/usr/lib/systemd/system/runlevel3.target -> multi-user.target
/usr/lib/systemd/system/runlevel4.target -> multi-user.target
/usr/lib/systemd/system/runlevel5.target -> graphical.target
/usr/lib/systemd/system/runlevel6.target -> reboot.target

デフォルトのターゲット (ランレベル) は以下で確認できます。

ls -l /etc/systemd/system/default.target
/etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.target

graphical.target ターゲットでは、実際にどんなサービスが起動するか

以下のように、graphical.target では、multi-user.target が持つサービスも同時に自動起動します。(Requires についてはここ)

cat /usr/lib/systemd/system/graphical.target|grep Requires
Requires=multi-user.target
ls /etc/systemd/system/multi-user.target.wants/
crond.service docker.service mysqld.service nginx.service...(etc)

つまり、システム起動時に cron/docker/mysql/nginx などが自動起動することがわかります

スポンサーリンク

ユニットとは

ユニットとは、1つのサービスとそれに関連する起動処理 (init) などをまとめたものです。

ユニットは、次の情報をカプセル化します。

・システムサービス
ソケットのリッスン
・init システムに関連するその他のオブジェクト

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/introduction-to-systemd_configuring-basic-system-settings#ref_systemd-unit-types_introduction-to-systemd

ユニットファイル (設定ファイル) では、サービスが自動起動するターゲット (ランレベル) などを設定します。

ユニットタイプ

ユニットには次のタイプが存在します。

ユニットのタイプユニットファイルの拡張子説明
サービスユニット.serviceシステムサービス
ターゲットユニット.targetsystemd ユニットのグループ
自動マウントユニット.automountファイルシステムの自動マウントポイント
デバイスユニット.deviceカーネルが認識するデバイスファイル
マウントユニット.mountファイルシステムマウントポイント
パスユニット.pathファイルシステム内のファイル,ディレクトリ
スコープユニット.scope外部作成のプロセス
スライスユニット.sliceシステムプロセスを管理する
階層的に構成されたユニットのグループ
ソケットユニット.socketプロセス間の通信ソケット
スワップユニット.swapスワップデバイスまたはスワップファイル
タイマーユニット.timersystemd タイマー
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/introduction-to-systemd_configuring-basic-system-settings#ref_systemd-unit-types_introduction-to-systemd
ls /usr/lib/systemd/system/
multi-user.target  mysqld.service user.slice (etc...)

ユニットファイルの場所と優先度

ユニットファイルは複数の場所に存在し、それぞれ優先度が異なります。(高い方の設定が優先)

優先度Path説明
1/etc/systemd/system/ユニット名.d/*.conf一部の設定を上書き
2/etc/systemd/system/ユニット名※全ての設定を上書き
3/etc/systemd/systemローカル設定
4/run/systemd/system実行時のユニット設定
5/usr/lib/systemd/systemパッケージインストール時点の設定
(つまり yum update で上書きされる)
※ユニット名 = crond.service など
systemd.unit(5) man ページ
https://gihyo.jp/admin/serial/01/ubuntu-recipe/0598?page=1

ユニットファイルの書き方

ユニットファイルは次の3つのセクションを持ちます。

セクション説明
[Unit]ユニットタイプに依存しない設定
[unit type]ユニットタイプに依存する設定
ユニットタイプがサービスユニットの場合、[Service] セクションとなる
[Install][systemctl enable], [systemctl disable] コマンドで、サービスユニットを有効化、無効化する時の設定

例えば、crond のサービスユニットファイルは以下のとおりです。

less /usr/lib/systemd/system/crond.service
[Unit]
Description=Command Scheduler
After=auditd.service systemd-user-sessions.service time-sync.target

[Service]
EnvironmentFile=/etc/sysconfig/crond
ExecStart=/usr/sbin/crond -n $CRONDARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=30s

[Install]
WantedBy=multi-user.target

Unit

セクション詳細
Descriptionユニットの説明
systemctl status <サービス名> コマンドで表示される説明
Documentationユニットのドキュメントの URI
Afterユニットが開始する順序 (ユニットの起動する順番) を設定
After で指定したユニットがアクティブになると、このユニットを開始します
Beforeユニットが開始する順序 (ユニットの起動する順番) を設定
このユニットがアクティブになると、Before で指定したユニットを開始します
Requiresユニットに依存関係 (並列に起動するユニット) を設定
指定したユニットが1つでもアクティブ化に失敗すると、このユニットは開始しません
Wantsユニットに依存関係 (並列に起動するユニット) を設定
指定したユニットが1つでもアクティブ化に失敗しても、このユニットは開始します
ConflictsRequires と反対の依存関係 (負の依存関係) を設定
指定したユニットと並列 (同時) に起動できないユニット
systemd.unit(5) man ページ
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files#tabl-Managing_Services_with_systemd-Unit_Sec_Options

crond のユニットファイルを変更してみます。(注:検証環境で実施ください)

sudo vim /usr/lib/systemd/system/crond.service
Description=Cahnge!!Command Scheduler
sudo systemctl daemon-reload
sudo systemctl status crond.service
crond.service - Cahnge!!Command Scheduler

crond.service の説明に「Change!!」が追加されていることが確認できました。

unit type (Service)

セクション詳細
Typeユニットの起動タイミングの指定
EnvironmentFile環境変数を読み込むファイル
ExecStartユニットの開始時に実行するコマンドまたはスクリプト
ExecStopユニットの停止時に実行するコマンドまたはスクリプト
ExecReloadユニットの再読み込み時に実行するコマンドまたはスクリプト
Restartユニットを再起動する条件
RemainAfterExitユニットのプロセスがすべて終了していてもアクティブと見なす
systemd.service(5)man ページ
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files#tabl-Managing_Services_with_systemd-Service_Sec_Options

Install セクション (自動起動の設定)

セクション詳細
RequiredBysystemctl enable 時に、<指定したユニット>.requires ディレクトリにシンボリックリンクを作成
WantedBysystemctl enable 時に、<指定したユニット>.wants ディレクトリにシンボリックリンクを作成
Alsosystemctl enable 時に、同時にシンボリックリンクを作成するユニット
systemd.unit(5) man ページ
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files#tabl-Managing_Services_with_systemd-Install_Sec_Options

実際にシンボリックリンクの削除、作成を行ってみます。

sudo systemctl disable crond.service
ls -l /etc/systemd/system/multi-user.target.wants/crond.service
No such file or directory
sudo systemctl enable crond.service
ls -l /etc/systemd/system/multi-user.target.wants/crond.service
/etc/systemd/system/multi-user.target.wants/crond.service -> /usr/lib/systemd/system/crond.service

[Install] セクションで [WantedBy=multi-user.target] と設定しているので、multi-user.target.wants ディレクトリ配下にシンボリックリンクが作成されました。

つまり、crond.service はターゲット (ランレベル) が multi-user.target でシステムを起動した際に、自動起動します。

スポンサーリンク

システムサービスの管理コマンド

systemd では、起動時の init だけでなく、運用中にもサービスを管理できます。

systemctl詳細
systemctl start <name>.serviceサービスを起動
systemctl stop <name>.serviceサービスを停止
systemctl restart <name>.serviceサービスを再起動
systemctl reload <name>.service設定を再読み込み
systemctl status <name>.serviceサービスのステータスを確認
systemctl list-units --type service --allすべてのサービスのステータスを表示
systemctl enable <name>.serviceサービスを有効化
(システム起動時に自動起動)
systemctl disable <name>.serviceサービスを無効化
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-services

systemd と cgroup

systemd は起動したプロセスを cgroup に配置することで階層的に管理します。

systemd-cgls
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize xx
├─docker
│ └─xxxxxxxxxxxxxxxxxxxxxxxx
│   └─xxxx /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 10
├─user.slice
│ └─user-xxxx.slice
│   └─session-xxxx.scope
│     ├─xxxx sshd: xxxxxx [priv]
│     ├─xxxx sshd: xxxxxx@pts/0
│     ├─xxxx -bash
│     ├─xxxx systemd-cgls
│     └─xxxx less
└─system.slice
  ├─docker.service
  │ └─xxxx /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
  ├─crond.service
  │ └─xxxx /usr/sbin/crond -n
  ├─mysqld.service
  │ └─xxxx /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

cgroup では、先ほど紹介したユニットタイプのうち、以下の3つを利用します。

ユニットのタイプユニットファイルの拡張子説明
サービスユニット.serviceシステムサービス
スコープユニット.scope外部作成のプロセス
スライスユニット.sliceシステムプロセスを管理する
階層的に構成されたユニットのグループ
-.slice - root スライス (上記の  systemd スライスにある PID 1 に相当)
system.slice: すべてのシステムサービスのデフォルト場所
user.slice - ユーザーセッションのデフォルトの場所
machine.slice: すべての仮想マシンおよび Linux コンテナーのデフォルト場所 (上記の docker に相当)
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/resource_management_guide/sec-default_cgroup_hierarchies
ls /usr/lib/systemd/system/*.slice
/usr/lib/systemd/system/-.slice        /usr/lib/systemd/system/system.slice
/usr/lib/systemd/system/machine.slice  /usr/lib/systemd/system/user.slice

関連情報

関連記事:Linux の基本機能

参考サイト

第10章 systemd によるサービス管理 Red Hat Enterprise Linux 7 | Red Hat Customer Portal
Access Red Hat’s knowledge, guidance, and support through your subscription.
第10章 systemd によるサービス管理 Red Hat Enterprise Linux 7 | Red Hat Customer Portal
Access Red Hat’s knowledge, guidance, and support through your subscription.