systemd と journalctl 運用 — 40+ コマンドを 5 カテゴリで

RHEL 7 / Ubuntu 16.04 以降、Linux のサービス管理は事実上 systemd 一択。 旧 SysV init の service / chkconfig から systemctl への置き換えが終わって長く、 EC2 でも RDS でも EKS Worker でも触れる場面が必ず出てきます。

目次

  1. サービス管理 (systemctl)
  2. ログ閲覧 (journalctl)
  3. unit ファイル作成・編集
  4. タイマー (cron 代替)
  5. 起動分析 / その他 (systemd-analyze / loginctl / timedatectl)
  6. 運用レシピ
  7. 用語集

1. サービス管理 (systemctl)

# 開始 / 停止 / 再起動 / リロード
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx           # 設定再読込(HUP 相当、無停止)
sudo systemctl reload-or-restart nginx

# 自動起動
sudo systemctl enable nginx           # 起動時に開始
sudo systemctl disable nginx
sudo systemctl enable --now nginx     # 即時開始 + 自動起動有効化
sudo systemctl disable --now nginx
sudo systemctl mask nginx             # 完全無効化(誰も start できなくする)
sudo systemctl unmask nginx

# 状態確認
systemctl status nginx                # 状態 + 直近ログ
systemctl is-active nginx             # active / inactive
systemctl is-enabled nginx            # enabled / disabled / masked
systemctl is-failed nginx             # failed?

# 一覧
systemctl list-units --type=service                    # 起動中サービス
systemctl list-units --type=service --state=failed    # 失敗中
systemctl list-units --all                             # 停止中含む
systemctl list-unit-files --type=service              # 全 unit ファイル

# unit の依存関係
systemctl list-dependencies nginx
systemctl list-dependencies nginx --reverse

# プロパティ表示・編集
systemctl show nginx                                    # 全プロパティ
systemctl show nginx --property=MainPID,ActiveState
sudo systemctl edit nginx                               # ドロップイン (.d/override.conf) 編集
sudo systemctl edit --full nginx                        # unit ファイル全文編集
sudo systemctl daemon-reload                            # 編集後はこれ必須

# システムレベル
sudo systemctl reboot
sudo systemctl poweroff
sudo systemctl suspend
sudo systemctl rescue                                   # シングルユーザモード相当
sudo systemctl emergency
sudo systemctl get-default                              # デフォルトターゲット (graphical / multi-user)
sudo systemctl set-default multi-user.target

2. ログ閲覧 (journalctl)

# 全ログ(古い→新しい順)
journalctl

# 末尾だけ + 追従
journalctl -f
journalctl -u nginx -f                       # 特定 unit の追従

# 特定 unit
journalctl -u nginx
journalctl -u nginx -u php-fpm               # 複数 unit
journalctl -u nginx --since '10 min ago'
journalctl -u nginx --since '2026-04-26 09:00' --until '2026-04-26 12:00'

# ログレベル
journalctl -p err -u nginx                   # err 以上 (emerg/alert/crit/err/warning/notice/info/debug)
journalctl -p warning..err                   # 範囲指定

# kernel ログ
journalctl -k                                # dmesg 相当
journalctl -k -b                             # 今回起動分のみ

# 起動順
journalctl -b                                # 今回起動
journalctl -b -1                             # 1 つ前の起動
journalctl --list-boots                      # 起動履歴
journalctl --reverse                         # 新しい順

# 出力形式
journalctl -o short-iso                      # 標準
journalctl -o cat                            # メッセージのみ
journalctl -o json                           # JSON
journalctl -o json-pretty | jq

# 容量管理
journalctl --disk-usage
sudo journalctl --vacuum-size=200M           # 200MB に切り詰め
sudo journalctl --vacuum-time=14d            # 14 日より古いを削除

# プロセスグループ別
journalctl _SYSTEMD_UNIT=nginx.service
journalctl _PID=1234
journalctl _UID=1000
journald は構造化ログ(フィールド付き)。-o json で取れば jq でフィルタ可能。 _SYSTEMD_UNIT, _HOSTNAME, MESSAGE_ID 等が使える。

3. unit ファイル作成・編集

unit ファイルの場所

/lib/systemd/system/      # ディストリ提供 (パッケージ)
/etc/systemd/system/      # ユーザ追加・上書き (こちらが優先)
~/.config/systemd/user/   # ユーザ単位 (systemctl --user)

シンプルな .service ファイル

# /etc/systemd/system/myapp.service
[Unit]
Description=My App
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
EnvironmentFile=/etc/myapp/env
StandardOutput=journal
StandardError=journal

# セキュリティ強化(推奨)
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/myapp
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

登録と起動

sudo systemctl daemon-reload                # 新規/編集後に必須
sudo systemctl enable --now myapp
journalctl -u myapp -f

ドロップイン(既存 unit を部分上書き)

sudo systemctl edit nginx
# エディタで以下のような部分上書きを書く
# [Service]
# LimitNOFILE=200000
# Environment="FOO=bar"

# 確認
systemctl cat nginx                          # 全有効設定(base + drop-in)

# 元に戻す
sudo systemctl revert nginx

4. タイマー (cron 代替)

cron に対する systemd 流儀の代替。実行が journald に残る・依存関係が書ける・unit と統一管理できる利点。

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

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

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

[Timer]
OnCalendar=*-*-* 03:00:00          # 毎日 03:00
RandomizedDelaySec=600             # ジッタ ±10 分
Persistent=true                    # 起動時に過去未実行を補完

[Install]
WantedBy=timers.target

# 有効化
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer

# 状態
systemctl list-timers --all
systemctl status backup.timer
journalctl -u backup.service       # 実行ログ

OnCalendar の書き方サンプル

OnCalendar=hourly                  # 毎時 0 分
OnCalendar=daily                   # 毎日 0 時
OnCalendar=Mon,Wed *-*-* 03:00:00 # 月水 03:00
OnCalendar=*-*-01 04:00:00        # 月初 04:00
OnCalendar=*-*-* 0/2:00:00        # 2 時間ごと

# テスト
systemd-analyze calendar 'Mon,Wed *-*-* 03:00:00'

5. 起動分析 / その他

systemd-analyze — 起動時間の分析

systemd-analyze                              # トータル起動時間
systemd-analyze blame                        # サービスごとの起動時間
systemd-analyze critical-chain               # クリティカルパス
systemd-analyze critical-chain nginx.service
systemd-analyze plot > boot.svg              # ガントチャート SVG
systemd-analyze verify /etc/systemd/system/myapp.service   # unit 構文チェック
systemd-analyze security nginx               # サービスのセキュリティ評価

loginctl — セッション管理

loginctl list-sessions
loginctl list-users
loginctl show-session 5
sudo loginctl terminate-session 5
sudo loginctl enable-linger www-data        # ユーザの user systemd を常時起動

timedatectl — 時刻管理

timedatectl                                  # 現在の時刻設定
sudo timedatectl set-timezone Asia/Tokyo
sudo timedatectl set-ntp true
timedatectl list-timezones | grep Tokyo

hostnamectl / localectl

hostnamectl                                  # hostname / kernel / OS 情報
sudo hostnamectl set-hostname web-01
localectl                                    # ロケール
sudo localectl set-locale LANG=ja_JP.UTF-8

運用レシピ

レシピ 1 — サービスが起動失敗してる

systemctl status myapp                       # 状態 + 直近 10 行ログ
journalctl -u myapp -n 100                   # 末尾 100 行
journalctl -u myapp -p err --since '1 hour ago'
sudo systemctl daemon-reload                 # unit 編集後の反映漏れ?
systemd-analyze verify /etc/systemd/system/myapp.service  # 構文OK?

レシピ 2 — ログを CloudWatch / 外部に送る

# journald のログを永続化(デフォルトで /var/log/journal)
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald

# CloudWatch Agent をインストールして journald を取り込み
# /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
# {"logs":{"logs_collected":{"journald":{"collect":[{...}]}}}}

# あるいは Vector / Fluent Bit で送る
journalctl -f --output=json -u myapp | vector ...

レシピ 3 — 起動が遅い

systemd-analyze
systemd-analyze blame | head -n 10
systemd-analyze critical-chain
systemd-analyze plot > boot.svg              # 視覚的に

レシピ 4 — タイマーが動いてない

systemctl list-timers --all                  # 次回実行時刻が見える
systemctl status backup.timer
journalctl -u backup.service                 # 過去実行のログ
systemctl cat backup.timer                   # OnCalendar 設定確認
systemd-analyze calendar 'Mon,Wed *-*-* 03:00:00'

コマンド早見表

# サービス
sudo systemctl enable --now myapp
sudo systemctl restart nginx
systemctl status nginx
systemctl list-units --type=service --state=failed

# ログ
journalctl -u nginx -f
journalctl -u nginx -p err --since '1 hour ago'
journalctl --disk-usage

# unit 編集
sudo systemctl edit nginx
sudo systemctl daemon-reload
systemctl cat nginx

# タイマー
systemctl list-timers --all
systemd-analyze calendar 'expression'

# 起動分析
systemd-analyze blame
systemd-analyze critical-chain

用語集

systemd
Linux の init システム + サービスマネージャ。RHEL 7 / Ubuntu 16.04 以降の標準。SysV init の service/chkconfig 後継。
unit
systemd の管理単位。.service / .timer / .socket / .target / .mount など。
target
複数 unit をまとめた論理グループ。multi-user.target = CUI 通常起動、graphical.target = GUI 含む。SysV のランレベル相当。
WantedBy / RequiredBy
「自分が起動すべき target」を指定するインストール時設定。WantedBy=multi-user.targetenable 時に target に紐付く。
Type=simple / forking / oneshot / notify
サービスのプロセス管理モード。simple = ExecStart がメイン / forking = デーモン化する / oneshot = 1 回実行で終わる / notify = 起動完了を sd_notify で通知。
ドロップイン (.d/override.conf)
既存 unit を部分上書きする仕組み。systemctl edit X で作成。元のパッケージを汚さずカスタマイズできる。
journald
systemd のログデーモン。構造化ログをバイナリ形式で保管、journalctl で閲覧・フィルタ。
systemd timer
cron に代わるスケジューラ。.timer unit + .service unit の対で動かす。実行ログが journald に残る、Persistent=true で見逃し補完できる。
OnCalendar
timer の実行スケジュール式。*-*-* 03:00:00(毎日 3 時)等。systemd-analyze calendar でテストできる。
systemd-analyze blame
各 unit の起動所要時間ランキング。起動の遅延ボトルネック特定に。
NoNewPrivileges / ProtectSystem / PrivateTmp
unit に書ける サービス強化オプション。最小権限・FS 保護・/tmp 隔離等。systemd-analyze security でスコア表示できる。
masked
unit を完全無効化した状態(/dev/null へのシンボリックリンク化)。disable よりも強力で、誰かが start しようとしても起動できない。
EnvironmentFile
unit が読み込む KEY=VALUE 形式のファイル。シークレットや環境別設定の分離に使う。
linger
ユーザがログアウトしてもユーザレベル systemd を継続起動させる設定。loginctl enable-linger USER
WantedBy=timers.target
タイマー unit を有効化する時の標準 target。これがないと enable しても自動起動しない。