メインコンテンツまでスキップ

Linux サービス管理の進化論:systemctl と service コマンドの違いと選び方

· 約9分
AIMDX 編集

Linux システム管理において、サービス(Service)の起動、停止、およびステータス監視は、日々の運用における基本スキルです。Linux ディストリビューションの進化に伴い、サービスの管理方法も大きなアーキテクチャの転換を経験しました。初期の SysVinit に基づく service コマンドから、現在主流の systemd とその関連ツール systemctl への移行です。

これら 2 つのツールの違いを理解することは、システム管理者の必須知識であるだけでなく、様々な年代のサーバー環境に直面した際に、正しい判断と対応を行うのに役立ちます。

systemctl と service の進化を示す図

背景:2 つの起動システムの歴史的文脈

SysVinit と service コマンド

初期の Linux システム(Debian 6、CentOS 5 など)では、最初に起動するプロセス(PID 1)として SysVinit(System V init)が採用されていました。このアーキテクチャでは、サービス管理は /etc/init.d/ ディレクトリに保存された Shell スクリプトを通じて実現されており、service コマンドはこれらのスクリプトを呼び出すための統一インターフェースでした。

# 従来の service コマンドの構文
service <サービス名> <アクション>

/etc/init.d/ 内の各ファイルは本質的に Shell スクリプトであるため、その機能、出力フォーマット、エラー処理の方法は完全に各作成者の実装に依存し、一貫した標準が欠けていました。

systemd と systemctl コマンド

2011 年頃から、systemd は徐々に SysVinit に取って代わり、Fedora、Ubuntu(15.04 以降)、Debian(8 以降)、CentOS/RHEL(7 以降)など、主要なディストリビューションの標準初期化システムとなりました。

systemctl は systemd の主要な管理コマンドであり、システムサービス(Unit)、マウントポイント、ソケット、タイマーなど、さまざまな systemd リソースの制御を担当します。

# systemctl コマンドの構文
systemctl <アクション> <サービス名>

構文の対比:一般的な操作の比較

以下では、nginx サービスを例にして、2 つのコマンドの一般的な操作を対比します。

操作service コマンド(旧式)systemctl コマンド(新式)
サービスの起動service nginx startsystemctl start nginx
サービスの停止service nginx stopsystemctl stop nginx
再起動service nginx restartsystemctl restart nginx
設定の再読み込みservice nginx reloadsystemctl reload nginx
ステータスの確認service nginx statussystemctl status nginx
自動起動の有効化chkconfig nginx onsystemctl enable nginx
自動起動の無効化chkconfig nginx offsystemctl disable nginx
自動起動設定の確認chkconfig --list nginxsystemctl is-enabled nginx

注意:SysVinit アーキテクチャでは、「サービスの起動」と「自動起動の設定」は別々のツール(service + chkconfig)に分かれていましたが、systemctl はこれら 2 つを同じツール内で統合管理しています。

重要なアーキテクチャの違い

1. 基盤となる実装メカニズム

service コマンドは本質的に /etc/init.d/<サービス名> の Shell スクリプトを呼び出すものであり、スクリプトのロジックや成功かどうかの判断基準は、完全にスクリプト作成者が独自に決定しています。

一方の systemctlUnit ファイル.service 形式)に依存しています。これらの設定ファイルは /lib/systemd/system/ または /etc/systemd/system/ ディレクトリに保存され、統一された INI 形式を採用しており、systemd が統括して解析および実行します。

# 代表的な systemd Unit ファイルの構成(/lib/systemd/system/nginx.service)
[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID

[Install]
WantedBy=multi-user.target

2. 並列起動能力

SysVinit は直列式の起動を採用しており、/etc/rc*.d/ 内のシンボリックリンクの番号に従って順番に実行されるため、各サービスは順番を待つしかありませんでした。

一方、systemd は**並列起動(Parallel Startup)**をサポートしています。サービス間の依存関係(After=, Requires=, Wants= などの指示)を分析することで、依存関係が許す前提の下で複数のサービスを同時に起動し、システムの起動時間を大幅に短縮します。

3. プロセスの管理と追跡

service コマンドはスクリプトの実行が完了すると終了するため、事後的にサービスプロセスの状態を知ることはできず、サービスから派生した子プロセスを管理することもできません。

systemd は cgroup(Control Groups) メカニズムを通じて、サービスのすべての関連プロセスを一括して管理します。サービスにより子プロセスが生成された場合でも、systemd は完全に追跡でき、サービス停止時にはすべての子プロセスが確実に一緒に終了されるため、ゾンビプロセス(Zombie Process)の発生を防ぎます。

4. ログの統合

service を使用して管理される従来のサービスは、通常、ログが /var/log/ ディレクトリ配下にある独自のカスタムファイルに散在しており、フォーマットが一貫していませんでした。

systemd には journald ログシステムが組み込まれており、systemd によって管理されるすべてのサービスの出力(stdout/stderr)は、構造化されたログデータベースに自動的にインポートされます。これは統一された journalctl コマンドで検索できます。

# nginx サービスのリアルタイムログを確認する
journalctl -u nginx -f

# 直近の 100 行のログを確認する
journalctl -u nginx -n 100

# 特定の期間のログを確認する
journalctl -u nginx --since "2026-04-01" --until "2026-04-16"

長所と短所の比較

service(SysVinit)の長所

  • 広範な互換性:非常に古いディストリビューションや組み込みシステムでは依然として唯一の選択肢です。
  • シンプルな構造:Init スクリプトは純粋な Shell スクリプトであり、Bash に慣れたシステム管理者にとっては理解や修正が容易です。
  • 低い依存性:特定の init システムフレームワークに依存せず、移植性が高いです。

service(SysVinit)の短所

  • 直列起動:サービスを順番に起動する必要があり、起動時間が長くなります。
  • プロセス追跡の欠如:サービスの停止時に子プロセスも一緒に終了されるか保証できません。
  • ログ管理の分散:各サービスのログフォーマットが不一致であり、統合検索が困難です。
  • 実装の一貫性の欠如:各 Init スクリプトの動作は作成の品質に完全に依存し、仕様が欠けています。

systemctl(systemd)の長所

  • 並列起動:システムの起動時間を大幅に短縮します。
  • 統一された Unit 形式:サービス設定が標準化され、可読性と保守性が高いです。
  • 完全なプロセス管理:cgroup を通じて追跡し、すべての派生プロセスを制御します。
  • 統合型ログシステム:journald により、構造化され、検索可能な統合ログを提供します。
  • 豊富な依存関係管理:サービスの依存関係と起動順序を正確に宣言できます。
  • 自動再起動メカニズムRestart=on-failure などの設定により、サービスがクラッシュした後の自動復旧を実現できます。

systemctl(systemd)の短所

  • 学習曲線が急:Unit ファイルの構文と systemd の全体概念には一定の学習時間が必要です。
  • 機能が大きすぎるという設計:一部の開発者は、systemd が過剰なシステム機能(ログ、ネットワーク、マウントなどを含む)を担っており、「Unix 哲学」である単一責任の原則に反していると批判しています。
  • 古いシステムには非対応:systemd 普及前の古いシステムやコンテナ環境では使用できない場合があります。

互換性レイヤー:現代のシステムにおける service コマンド

注目すべき点は、systemd が導入された現代の Linux ディストリビューションにおいて、service コマンドが消滅したわけではなく、 互換性ラッパーレイヤー(Compatibility Shim) として存在し続けていることです。

service nginx start を実行すると、システムは後方互換性のあるコマンドインターフェースを提供するために、内部で自動的に systemctl start nginx の呼び出しに転送します。つまり、現代のシステムでは両者の実行結果はほぼ同じですが、service が提供する出力情報は比較的限定されています。

# Ubuntu 22.04 で service を実行すると、実際には内部で systemctl を呼び出しています
$ service nginx start
# 以下と同じです
$ systemctl start nginx

ツール選択の指針

使用シナリオお勧めのツール
現代の Linux ディストリビューション(Ubuntu 16.04+、CentOS 7+、Debian 8+)systemctl
古いシステム(Ubuntu 14.04-、CentOS 6-、Debian 7-)service
バージョン間互換性が必要なスクリプトの作成検出後に条件付きで選択
サービスの詳細なログを確認したい場合systemctl status + journalctl
組み込み Linux などの軽量環境service(実際の init システムによる)

以下は、Shell スクリプト内で init システムを検出し、対応するコマンドを選択する実装例です。

#!/bin/bash
SERVICE_NAME="nginx"

if command -v systemctl &>/dev/null && systemctl list-units &>/dev/null; then
echo "systemctl を使用してサービスを管理します"
systemctl restart "$SERVICE_NAME"
else
echo "service を使用してサービスを管理します(SysVinit 環境)"
service "$SERVICE_NAME" restart
fi

まとめ

servicesystemctl は、Linux サービス管理における 2 つの世代を代表しています。前者はシンプルな Shell スクリプトに基づいており、古いまたは軽量な環境に適しています。後者は systemd の統合フレームワークを通じて提供され、並列起動、プロセス追跡、構造化ログなどの現代的な管理機能を提供します。

現代のサーバー環境における圧倒的多数で、systemctl は事実上の標準となっています。その構文と Unit ファイルの設定を熟練して習得することは、現代の Linux 環境で効率的に運用するための基礎的なスキルと言えるでしょう。