基礎

systemdとは:仕組みとLinuxサービスの管理方法

更新日: · Skillaria.Top

systemdはLinuxの初期化システムであり、サービスマネージャです。カーネルが起動後に最初のプロセス(PID 1)として起動し、他のサービスを正しい順序で立ち上げて監視します。systemdの機能はすべてユニットで設定されます。ユニットは、サービス、タイマー、マウントポイントなどを記述するテキストファイルです。systemctl で起動、停止、自動起動の設定を行い、journalctl でログを確認します。

systemdは、初期化システムおよびサービスマネージャで、Debian、Ubuntu、Fedora、RHELおよびその派生ディストリビューションなど、現代の多くのLinuxで使われています。カーネルは起動後にsystemdをPID 1のプロセスとして実行し、その後ネットワークの設定、ディスクのマウント、Webサーバー、データベース、その他すべてのサービスを立ち上げます。簡単に言えば、systemdは「どのサービスを動かすべきか、どの順序で起動するか、サービスが落ちたらどうするか」を知っている管理役です。

お使いのシステムがsystemdを使っているかは、次のコマンドで確認できます。

$ ps -p 1 -o comm=
systemd

systemdが必要になった理由

以前のLinuxはSysV initを使っていました。/etc/init.d/ にあるシェルスクリプトを順番に実行する仕組みです。分かりやすいものの、遅く、壊れやすいものでした。各スクリプトが自分でPIDファイルを書き、プロセスが生きているかを判断し、異常終了したサービスの再起動は別途仕組みを作る必要がありました。

systemdは、これらの課題を一元的に解決します。

  • 並列起動。依存関係のないサービスは同時に起動するため、起動が速くなります。
  • 依存関係と順序。サービスの定義に、必要なもの(たとえばネットワーク)と起動の順序を明記します。
  • 監視。systemdはcgroupsを使ってサービスのすべてのプロセスを把握し、障害時には再起動できます。
  • 統一されたログ。すべてのサービスの出力はjournaldが集め、1つのコマンドで確認できます。
  • 統一されたインターフェース。どのサービスも同じ方法で管理します。systemctl start|stop|restart|status。

サービスマネージャ以外にも、systemdプロジェクトには複数のコンポーネントが含まれます。journald(ログ)、logind(ユーザーセッション)、timesyncd(時刻同期)、resolved(DNS)、networkd(ネットワーク)です。すべてのディストリビューションがすべてを使うわけではありませんが、PID 1としてのsystemdとjournaldはほぼどこにでもあります。

ユニット:systemdの構成要素

systemdが管理するものはすべてユニット(unit)で記述されます。ユニットはINI形式のテキストファイルで、ユニットの種類は拡張子で決まります。

種類拡張子記述の対象
service.serviceサービス:デーモンまたは単発のタスク
timer.timerスケジュールに従って別のユニットを起動(cronの代わり)
socket.socketソケット。接続があったときにサービスを起動
target.targetユニットのグループ、つまり「システムの状態」(例:multi-user.target)
mount.mountマウントポイント
path.pathファイルやディレクトリの監視

ユニットファイルの場所

ユニットファイルは複数のディレクトリにあり、優先順位があります。

  • /usr/lib/systemd/system/(DebianとUbuntuでは /lib/systemd/system/ も):パッケージでインストールされたユニット。直接編集しないでください。パッケージを更新すると変更が上書きされます。
  • /etc/systemd/system/:管理者のユニットと上書き設定。最も優先されます。
  • /run/systemd/system/:実行中に作成される一時的なユニット。

上書き設定を含めた最終的なユニットの内容は systemctl cat nginx.service で確認できます。

ランレベルの代わりにターゲット

古いランレベルはターゲット(target)に置き換えられました。multi-user.target はグラフィカルでない通常のサーバーモード、graphical.target はグラフィカルなデスクトップ、rescue.target はシングルユーザーの復旧モードです。現在のデフォルトのターゲットは systemctl get-default で、変更は systemctl set-default multi-user.target で行います。

systemctl:サービスを管理する

systemctl はsystemdを操作する主要なツールです。システムの状態を変更するコマンドのほとんどには sudo が必要です。

コマンド内容
systemctl status nginxサービスの状態、PID、メモリ、直近のログ行
systemctl start nginx今すぐ起動
systemctl stop nginx停止
systemctl restart nginx再起動(stop + start)
systemctl reload nginx停止せずに設定を再読み込み(サービスが対応している場合)
systemctl enable nginx自動起動を有効化
systemctl disable nginx自動起動を無効化
systemctl enable --now nginx自動起動を有効化して、すぐ起動
systemctl is-active nginxactive/inactive を表示。スクリプトで便利
systemctl list-units --type=service読み込まれているサービス
systemctl --failed失敗しているユニット
systemctl daemon-reloadユニットファイルを編集した後に再読み込み

systemctl status の読み方

$ systemctl status nginx
● 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 Mon 2026-10-12 09:14:03 UTC; 2h 5min ago
       Docs: man:nginx(8)
   Main PID: 812 (nginx)
      Tasks: 3 (limit: 2307)
     Memory: 6.1M
        CPU: 154ms
     CGroup: /system.slice/nginx.service
             ├─812 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             ├─813 "nginx: worker process"
             └─814 "nginx: worker process"

Loaded の行は、ユニットファイルの場所と自動起動が有効(enabled)かどうかを示します。Active の行は現在の状態で、active (running)、inactive (dead)、failed のいずれかです。CGroup の欄にはサービスのすべてのプロセスが表示され、systemdはこの仕組みで、どのプロセスがそのサービスに属するかを把握しています。

enable と start の違い

これはよくある混乱です。start はサービスを今すぐ起動しますが、再起動後には自動では起動しません。enable は対象のターゲットのディレクトリ(例:/etc/systemd/system/multi-user.target.wants/)にシンボリックリンクを作成します。そのため、起動時にサービスが立ち上がりますが、今は起動しません。両方が必要な場合がほとんどなので、enable --now を使います。

3つ目の状態は mask です。systemctl mask service はユニットを /dev/null にリンクし、手動でも依存関係からも起動できなくなります。サービスを確実に無効化したいときに使います。

journalctl:サービスのログ

サービスがstdoutとstderrに書いた内容はすべて systemd-journald が取り込み、ユニット名、PID、優先度、時刻などのメタデータとともにバイナリのジャーナルに保存します。ジャーナルは journalctl で読みます。

journalctl -u nginx              # 1つのサービスのログ
journalctl -u nginx -f           # リアルタイムで監視。tail -f と同様
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx -n 50        # 末尾50行
journalctl -b                    # 現在の起動以降
journalctl -b -1                 # 1つ前の起動
journalctl -p err -b             # エラー以上の重大度のみ
journalctl -k                    # カーネルのメッセージ
journalctl --disk-usage          # ジャーナルが使っている容量

-p オプションはsyslogの優先度で絞り込みます。emerg、alert、crit、err、warning、notice、info、debug があり、指定したレベルより重大なものがすべて表示されます。

再起動後もログを残す

/var/log/journal ディレクトリが存在せず、/etc/systemd/journald.conf に Storage=auto が設定されていると、ジャーナルはメモリ(/run/log/journal)にだけ保存され、再起動すると消えます。永続化するには Storage=persistent を設定するか、ディレクトリを作成してjournaldを再起動します。サイズは SystemMaxUse= で制限でき、古いログは journalctl --vacuum-time=2weeks や --vacuum-size=500M で削除できます。

journaldはrsyslogと組み合わせて使われることもよくあります。journaldがメッセージをrsyslogに渡し、rsyslogが従来のテキストログを /var/log/ に書き、ログを中央サーバーに転送します。

独自のサービスを自動起動させる:ユニットファイルの例

たとえば、常に動かしておきたく、起動時に立ち上げ、障害時には再起動させたいアプリケーション(スクリプトまたはバイナリ)があるとします。/etc/systemd/system/myapp.service を作成します。

[Unit]
Description=My web application
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
EnvironmentFile=/etc/myapp/env
ExecStart=/opt/myapp/bin/server --port 8080
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

各セクションの意味は次のとおりです。

  • [Unit]:説明と依存関係。After= は順序だけを決めます。Wants= は弱い依存関係で、ユニットを起動しようとしますが、起動に失敗しても自分は失敗しません。強い依存関係には Requires= を使います。
  • [Service]:起動方法。Type=simple は ExecStart のプロセスがサービスそのものであり、バックグラウンドに移行しないことを意味します。User= は権限の低いユーザーで実行します。Restart=on-failure はエラーで終了した場合に RestartSec 秒後に再起動します。
  • [Install]:enable したときの動作。WantedBy=multi-user.target は「通常の起動時に開始する」という意味です。

適用します。

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
systemctl status myapp
journalctl -u myapp -f

ユニットファイルでよくあるミス

  • ExecStart に相対パスを書く。プログラムのパスは絶対パスにしてください。systemdは、シェルのようにユーザーの PATH からコマンドを探しません。
  • daemon-reload を忘れる。ファイルを変更した後もsystemdは古いバージョンを使い続け、status で警告を表示します。
  • デーモンがバックグラウンドに移行する。プログラムが自分でforkするのに Type=simple を指定すると、systemdはサービスが終了したと判断します。プログラムをフォアグラウンドで動かすか、Type=forking と PIDFile= を使ってください。
  • プロファイルの環境変数を使う。サービスは ~/.bashrc や /etc/profile を読みません。変数は Environment= または EnvironmentFile= で設定します。

パッケージのユニットを変更せずに上書きする

パッケージに含まれるサービスの設定を変えたいが、そのファイルには触れたくない場合は、drop-in(上書き設定)を使います。

sudo systemctl edit nginx

エディタが開き、変更は /etc/systemd/system/nginx.service.d/override.conf に保存されます。たとえば [Service] セクションに Restart=always を書き加えられます。エディタを閉じると、systemdが設定を自動的に再読み込みします。

cronの代わりにsystemdタイマーを使う

タイマーは、同じ名前のサービスをスケジュールに従って起動するユニットです。cronと比べると、タスクのログがジャーナルに残り、依存関係を宣言でき、実行を逃したタスクを後から実行できます(Persistent=true)。毎日のバックアップを例にします。

# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers

OnCalendar の書式は systemd-analyze calendar "*-*-* 03:00:00" で確認できます。次回の実行時刻が表示されます。

起動時間の診断

systemdは各ユニットの起動時刻を記録しているので、起動の遅さを簡単に調べられます。

systemd-analyze                  # 起動全体の時間
systemd-analyze blame            # 起動にかかった時間順のユニット
systemd-analyze critical-chain   # 起動を遅らせている連鎖
systemd-analyze verify /etc/systemd/system/myapp.service   # ユニットファイルの検証

まとめ

systemdは、現代のLinuxにおけるPID 1であり、サービスマネージャです。すべてをユニットで記述し、systemctl で管理し、ログをジャーナルに集め、journalctl で読みます。cronの代わりにタイマーでタスクを実行することもできます。実用的に使うには、status、enable --now、journalctl -u を覚え、Restart=on-failure を持つ簡単なユニットファイルを書けるようになれば十分です。systemd、journald、ログの扱いは、Linuxコースで実践を通して解説しています。

よくある質問

自分のシステムがsystemdを使っているかどうかは、どうすれば分かりますか?

ps -p 1 -o comm= を実行します。出力が systemd なら、systemdで動いています。また、/run/systemd/system ディレクトリは、systemdで起動したときにのみ存在します。

systemctl restart と reload の違いは何ですか?

restart はサービスを完全に停止してから再び起動するため、接続が切れます。reload はサービスに停止せず設定を再読み込みするよう要求しますが、ユニットに ExecReload が定義されている場合にのみ使えます。

sudoを使わずに、一般ユーザーとしてsystemdのサービスを動かせますか?

はい。systemdにはユーザーインスタンスがあります。ユニットファイルを ~/.config/systemd/user/ に置き、systemctl --user で管理します。ログインしていなくても動かすには、そのユーザーに対して loginctl enable-linger を実行します。

サービスがfailedになる原因は何ですか? その状態はどうやってリセットしますか?

原因は journalctl -u 名前 -b と status の Active の行で確認できます。問題を修正したらサービスを再起動します。再起動せずに failed の表示だけを消すには systemctl reset-failed を使います。

systemdのログはディスクのどこに保存されますか?

永続化されている場合は /var/log/journal/ にバイナリ形式で、そうでなければメモリ上の /run/log/journal/ に保存されます。テキストツールで直接開くのではなく、journalctl で読んでください。

動画でこのテーマを学ぶ

このテーマはコース「Linux: с нуля до уверенного администрирования」で実践とともに詳しく解説しています。

コースへ