systemd と journalctl 運用 — 40+ コマンドを 5 カテゴリで
RHEL 7 / Ubuntu 16.04 以降、Linux のサービス管理は事実上 systemd 一択。
旧 SysV init の service / chkconfig から systemctl への置き換えが終わって長く、
EC2 でも RDS でも EKS Worker でも触れる場面が必ず出てきます。
目次
- サービス管理 (systemctl)
- ログ閲覧 (journalctl)
- unit ファイル作成・編集
- タイマー (cron 代替)
- 起動分析 / その他 (systemd-analyze / loginctl / timedatectl)
- 運用レシピ
- 用語集
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.targetでenable時に 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 に代わるスケジューラ。
.timerunit +.serviceunit の対で動かす。実行ログが 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 しても自動起動しない。