systemd とは何か

現在の主要な Linux ディストリビューションの多くは、systemdinit システム(カーネル起動直後に最初に動き、他のすべてのプロセスを管理する仕組み)として採用しています。systemd は各種サービスを「ユニット」という単位で管理します。ユニットには .service(常駐プログラム)、.timer(定期実行)、.socket.mount などの種類があり、日常的に触れるのはほぼ .service です。

この systemd を操作するコマンドが systemctl、systemd が集めたログを読むコマンドが journalctl です。この2つを押さえれば、サービス管理の大半は完了します。以下のコマンド例は特定のディストリビューションに依存しません(パッケージ名やサービス名だけは環境ごとに読み替えてください)。

ステップ1: サービスの状態を確認する

まずは現状把握です。何かを変更する前に、必ず状態を見る癖をつけてください。

systemctl status sshd

ユニット名の .service は省略できます(sshdsshd.service と解釈される)。稼働中のサービス一覧や、失敗しているものだけを見たいときは次のようにします。

# サービス一覧(インストール済みで未起動のものも含める)
systemctl list-units --type=service --all

# 失敗しているユニットだけを表示
systemctl --failed

スクリプトから判定したい場合は、終了コードで結果を返す専用サブコマンドが便利です。

systemctl is-active sshd    # 稼働中か
systemctl is-enabled sshd   # 自動起動が有効か

ステップ2: 起動・停止・再起動

システム全体のサービスを操作するには管理者権限が必要なので、sudo を付けます。

sudo systemctl start   nginx   # 起動
sudo systemctl stop    nginx   # 停止
sudo systemctl restart nginx   # 停止してから起動
sudo systemctl reload  nginx   # 設定だけ再読み込み(プロセスは継続)

reload は、そのサービスが再読み込みに対応している場合のみ使えます。対応しているか分からないときは sudo systemctl reload-or-restart nginx を使うと、対応していなければ自動的に再起動へフォールバックします。稼働中のサービスへの設定反映は、接続を切らずに済む reload が原則として安全です。

ステップ3: 自動起動(OS 起動時の有効化)を設定する

ここが初心者のつまずきやすいポイントです。startenable は別物で、前者は「いま動かす」、後者は「次回以降の OS 起動時にも動かす」を意味します。

sudo systemctl enable  nginx        # 次回起動から自動起動する
sudo systemctl disable nginx        # 自動起動をやめる
sudo systemctl enable --now nginx   # 自動起動を有効化し、同時に今すぐ起動
sudo systemctl disable --now nginx  # 自動起動を無効化し、同時に今すぐ停止

さらに強く「絶対に起動させたくない」場合は mask があります。mask したユニットは、他のサービスからの依存で呼ばれても起動しません。解除は unmask です。誤って mask したまま原因不明の起動失敗に悩むケースがあるので、使ったことは記録しておきましょう。

ステップ4: status 出力の読み方

systemctl status の出力は情報が詰まっています。主要な行の意味は次のとおりです。

意味
Loaded:ユニットファイルの場所と、自動起動が enabled / disabled / masked のどれか
Active:現在の状態と、その状態になった時刻
Main PID:本体プロセスのプロセス ID。終了時は終了コードも表示される
CGroup:このサービスに属する全プロセス。子プロセスの取りこぼしが分かる
末尾の数行そのユニットに関する直近のログ抜粋

Active: の値は特に重要です。active (running) は常駐プロセスが動いている状態、active (exited) は「正常に処理を終えて終了した」状態(一度きりの初期化処理などで正常)、inactive (dead) は停止中、failed は異常終了です。activating のまま止まっている場合は、起動処理が完了せずタイムアウト待ちになっている可能性があります。

ステップ5: journalctl でログを絞り込む

systemd はサービスの標準出力・標準エラー出力を journal という仕組みで一元管理します。これを読むのが journalctl です。まず覚えるべきは ユニット指定起動セッション指定の2つです。

# 特定サービスのログだけ
journalctl -u nginx

# 今回の OS 起動以降のログだけ(-b = boot)
journalctl -u nginx -b

# 直近50行を末尾から表示
journalctl -u nginx -n 50

# tail -f のようにリアルタイム追尾
journalctl -u nginx -f

期間や重要度でも絞り込めます。-p は優先度(priority)で、emerg, alert, crit, err, warning, notice, info, debug の順に緩くなり、指定した以上に深刻なものがすべて表示されます。

journalctl --since "1 hour ago"
journalctl --since today --until "12:00"
journalctl -p err -b            # エラー以上のみ、今回起動分
journalctl -k                   # カーネルメッセージのみ

過去の起動時のログを見たい場合は journalctl --list-boots で一覧を出し、journalctl -b -1 のように1つ前の起動を指定します。ただし再起動をまたいでログが残るかはディストリビューションの設定に依存します/var/log/journal ディレクトリが存在すれば永続化されており、無ければ再起動で消えます。永続化したい場合は /etc/systemd/journald.confStorage=persistent を設定します。

ログが肥大化してきたら容量を確認・整理できます。

journalctl --disk-usage
sudo journalctl --vacuum-time=2weeks   # 2週間より古いものを削除
sudo journalctl --vacuum-size=500M     # 合計500MB以下に切り詰め

なお一般ユーザーが自分以外のログを読めるかは権限設定次第です。読めない場合は sudo を付けるか、ユーザーを systemd-journal グループ(ディストリビューションによっては adm)に追加してください。

ステップ6: 起動しないサービスの原因切り分け

「起動しない」ときは、次の順で機械的に調べると原因にたどり着けます。

  1. 失敗の事実と終了コードを確認するsystemctl status サービス名 を実行し、Active: failed の括弧内(Result:)と終了コードを見ます。
  2. 詳しい説明付きでログを読むjournalctl -xeu サービス名 を実行します。-x は systemd による補足説明を追加、-e は末尾から表示、-u はユニット指定です。実際のエラーメッセージはほぼここに出ます。
  3. 設定ファイルの構文を疑う ― サービス自身の設定ミス(ポート重複、パスの誤り、権限不足)が最頻出です。多くのサーバーソフトは設定検証コマンドを持っているので、それを先に通します。
  4. ユニットファイルを確認するsystemctl cat サービス名 で、実際に読み込まれているユニット定義と後述の追加設定をまとめて表示できます。ExecStart= のパスが存在するかを確かめてください。
  5. ユニットの文法を検証する ― 自作ユニットなら systemd-analyze verify /etc/systemd/system/自作.service で記述ミスを検出できます。
  6. 依存関係を確認するsystemctl list-dependencies サービス名 で、前提となるサービス(データベースやネットワーク)が起動しているかを見ます。前提側が落ちていれば、そちらが真の原因です。

原因を直したあとも failed 表示が残る場合は sudo systemctl reset-failed サービス名 で失敗カウントをクリアできます。

ユニット設定を変更するときの鉄則

パッケージが提供するユニットファイル(多くは /usr/lib/systemd/system/ 配下)を直接編集してはいけません。パッケージ更新で上書きされてしまいます。代わりにドロップインという上書き設定を使います。

sudo systemctl edit サービス名

これにより /etc/systemd/system/サービス名.service.d/override.conf が作られ、必要な項目だけを上書きできます。全文をコピーして編集したい場合は sudo systemctl edit --full サービス名 です。

また、ユニットファイルを手作業で追加・編集した場合は、systemd に読み直させる必要があります。

sudo systemctl daemon-reload

「編集したのに反映されない」という相談の多くは、この daemon-reload 忘れが原因です。systemctl edit 経由なら自動で実行されます。

ユーザー単位のサービス

ここまではシステム全体のサービスでしたが、ログインユーザー自身のプロセスを管理する仕組みもあります。--user を付けるだけで、sudo なしに同じ操作ができます。

systemctl --user status myapp
journalctl --user -u myapp -f

自分専用の常駐スクリプトなどは、システム全体を触らずにこちらで管理すると安全です。

まとめ

覚えるべきコマンドは多くありません。状態を見る systemctl status、動かす start / stop / restart、次回以降に効かせる enable、そしてログを読む journalctl -xeu。この4系統で日常の運用はほぼカバーできます。特に「startenable は別」「ユニット編集後は daemon-reload」「困ったら journalctl -xeu」の3点は、トラブル対応の時間を確実に短縮してくれます。より詳しい仕様は公式サイト systemd.io や、各コマンドの man systemctl / man journalctl を参照してください。