PK
パーネルカニック研究所
今日もどこかでkernel panic。
root@pk-lab:~#

systemdとは何か

連載ナビ

この連載は「Linuxを使えるようになる」ではなく、「Linuxがどう動いているのか」を理解するための実践シリーズです。

今回は Linuxを理解する 〜 LFSで学ぶLinux内部構造 〜 の Part 5 / 第3回として、仕組みのつながりを意識しながら学びます。

—

systemdは「PID 1として全サービスを起動・監視するinitシステム」

前回の起動シーケンスの最後で、カーネルは本物のルート上の /sbin/init を実行しました。UbuntuやRHEL系を含む主要ディストリビューションで、この最初のプロセス(PID 1)を務めるのがsystemdです。

結論から言うと、systemdとは、システム上のあらゆる管理対象を「unit」という単位で定義し、unit間の依存関係に基づいて並列に起動・監視するinitシステムです。自分の環境で確かめるのは簡単です。


$ ps -p 1 -o pid,comm
  PID COMMAND
    1 systemd

unitには種類があり、ファイルの拡張子で区別されます。代表的なものだけ挙げます。

  • .service — サービス(nginxやsshdなどのプロセス)の起動定義
  • .socket — ソケットの待ち受け(接続が来たら対応するserviceを起動する)
  • .timer — 時刻や間隔による起動(cronの代替)
  • .target — 複数unitの束ね役(multi-user.target など、従来のランレベルに相当)

「サービスを起動する」「定期実行する」「起動順序を制御する」が、すべて同じ仕組み(unitファイル)で記述できるのがsystemdの特徴です。

「シェルスクリプトを順番に実行する」方式の限界を超えるため

なぜsystemdが主要ディストリビューションに採用されたのか。理由は、従来のinitシステム(SysV init)が抱えていた3つの問題を解決するからです。

1. 起動が直列で遅い: SysV initは /etc/rc.d/ 以下のシェルスクリプトを番号順に1つずつ実行していました。systemdはunitファイルに書かれた依存関係(After= など)を解析し、依存のないunit同士を並列に起動します

2. 依存関係が暗黙的: 「スクリプトの番号を手で調整して順序を作る」方式では、何が何に依存しているのか definitionとして残りません。systemdでは After=network.target のように依存が宣言的に書かれ、systemctl list-dependencies で可視化できます

3. プロセスの監視ができない: SysV initは起動スクリプトを実行したら終わりで、サービスが落ちても気づけませんでした。systemdは各サービスをcgroup(カーネルのプロセスグループ管理機構)に入れて追跡し、Restart=on-failure と書くだけで自動再起動を実現します

DockerやKubernetesを触っている方なら、「宣言的な定義」「ヘルスチェックと自動再起動」という発想に馴染みがあるはずです。systemdは、それをOSのサービス管理に持ち込んだものと捉えると理解が早いです。

unitファイルを読んでみる

サービスの定義は、iniファイル風のunitファイルに書かれています。置き場所は主に2つあり、優先順位が決まっています。

  • /lib/systemd/system/(または /usr/lib/systemd/system/)— パッケージが提供する定義
  • /etc/systemd/system/ — 管理者が置く定義。同名ファイルがあればこちらが優先

nginxをインストールした環境なら、/lib/systemd/system/nginx.service はおおよそこんな内容です。


[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target

[Service]
Type=forking
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
Restart=on-failure

[Install]
WantedBy=multi-user.target
  • [Unit] セクション: 説明と依存関係。After=network.target は「ネットワーク準備の後に起動する」という順序指定です
  • [Service] セクション: 起動コマンド(ExecStart=)、プロセスの型(Type=)、障害時の挙動(Restart=)
  • [Install] セクション: systemctl enable したときにどのtargetに紐づくか

この enable の仕組みは具体的で、systemctl enable nginx を実行すると、実体としては /etc/systemd/system/multi-user.target.wants/nginx.service というシンボリックリンクが作られるだけです。「自動起動の設定」の正体がただのシンボリックリンクだと知っていると、ls /etc/systemd/system/multi-user.target.wants/ で「起動時に上がるサービスの一覧」を直接確認できます。

systemctlでの操作と、status出力の読み方

日常操作はほぼ systemctl に集約されます。


# いま動いているサービスの一覧
systemctl list-units --type=service --state=running

# 個別サービスの状態確認・起動・停止・再起動
systemctl status nginx
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx

# 自動起動の有効化/無効化(シンボリックリンクの作成/削除)
sudo systemctl enable nginx
sudo systemctl disable nginx

# unitファイルを編集したら必ず実行(定義の再読み込み)
sudo systemctl daemon-reload

systemctl status の出力は情報の宝庫なので、読み方を押さえておきます。


● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-08-21 10:00:00 UTC; 2h ago
   Main PID: 1234 (nginx)
      Tasks: 3
     Memory: 4.0M
     CGroup: /system.slice/nginx.service
             ├─1234 "nginx: master process /usr/sbin/nginx"
             └─1235 "nginx: worker process"
  • Loaded: — 読み込まれたunitファイルのパスと、自動起動設定(enabled/disabled)
  • Active: — 現在の状態。active (running) 以外に、正常終了済みの inactive (dead)、起動失敗の failed などがある
  • Main PID: / CGroup: — 管理しているプロセスの実体。cgroupの木構造で、masterとworkerの親子関係まで見える

障害調査ではまず systemctl status で Active: の行と末尾の直近ログを見る、が定石の初手になります。

PID 1の仕事が分かると、その配下の「常駐プロセス」が見えてくる

systemdは、unitという宣言的な定義に基づき、依存関係を解決しながらサービスを並列起動し、cgroupで監視し続けるPID 1である——これが今回のポイントです。LFSブックの標準構成では実はsystemdではなくSysV initを採用しており、両方を知ることで「initシステムは交換可能な部品である」という前回までの話ともつながります。

ところで、systemdが起動・監視している「サービス」の実体は、バックグラウンドで常駐し続けるプロセスです。この常駐プロセスにはdaemonという伝統的な呼び名と、独特の作法があります。次回はその中身を見ていきます。

図解テキスト


systemd (PID 1)
  -> target(multi-user.target などの束ね役)
  -> service / socket / timer(個々のunit)

unitファイルの置き場所:
  /lib/systemd/system/  … パッケージ提供
  /etc/systemd/system/  … 管理者用(こちらが優先)

systemctl enable の実体:
  /etc/systemd/system/multi-user.target.wants/xxx.service -> シンボリックリンク作成

この回で実行するコマンド

上から順番に実行すれば、この回の内容を体験できます。

まずはそのままコピペして実行し、次に1行ずつ意味を確認してください。


# PID 1がsystemdであることを確認
ps -p 1 -o pid,comm

# 動作中のサービス一覧
systemctl list-units --type=service --state=running | head -n 40

# sshdの状態を確認(環境によりunit名は ssh の場合あり)
systemctl status sshd 2>/dev/null || systemctl status ssh 2>/dev/null || true

# 自動起動に登録されているサービスの実体(シンボリックリンク)を見る
ls -l /etc/systemd/system/multi-user.target.wants/ 2>/dev/null | head -n 20

ハンズオン手順

1. ターミナルを開いて、上のコマンドを1行ずつ実行する

2. systemctl status の出力から Loaded: Active: Main PID: の3行を探して意味をメモする

3. cat /lib/systemd/system/ssh.service(またはsshd.service)でunitファイルを開き、ExecStart= の行を見つける

4. エラーが出たら、そのエラーメッセージをそのまま残す

チェックポイント

  • コマンドが最後まで実行できた
  • unitファイルの [Unit] [Service] [Install] 各セクションの役割を言える
  • systemctl enable が実際に何をしているか(シンボリックリンク作成)を説明できる
  • 次の回に進む前に、分からない単語を1つ調べた

今回理解できたこと

  • systemdは起動オーケストレーター(PID 1として依存関係を解決し並列起動する)
  • unitの依存関係理解が重要(After= / WantedBy= / list-dependencies)
  • サービスはcgroupで追跡され、Restart= で自動再起動できる