2 分で読了 #linux #systemd #devops #ops
このページの目次

systemd 操作マニュアル

systemd は Linux のユーザー空間における init システムおよびサービスマネージャーです。ユニットタイプ(service/timer/socket/mount)、依存関係、ログシステム、オーバーライドメカニズムを理解することは、運用管理の基礎となります。

プロセス確認: btm (bottom, top の代替 — CPU/メモリ/ディスク/温度の TUI), procs (ps の代替 — カラースタイル, 自動カラム幅, プロセスツリー)

ステータスの確認

# ユニットの状態、最新のログ10行、cgroup ツリー、メイン PID を表示
systemctl status nginx
# Active: active (running) since ... — 実行中
# Active: inactive (dead) — 停止中
# Active: failed — 起動失敗 (終了コードを確認)

# 全ユニットをリスト表示し、状態別にフィルタリング
systemctl list-units                    # ロードされた全ユニット
systemctl list-units --state=failed    # 失敗したユニットのみ表示
systemctl list-units --type=service    # service のみ表示
systemctl list-units --type=timer      # timer のみ表示

# ユニットが有効化されているか(起動時に自動起動するか)を確認
systemctl is-enabled nginx
systemctl is-active nginx              # 実行中かどうか

# ユニットの依存関係ツリーを表示
systemctl list-dependencies nginx
systemctl list-dependencies nginx --reverse  # どのユニットがこれに依存しているか

# ユニットファイルの内容(すべての drop-in を含む)を表示
systemctl cat nginx

# 全タイマーと次回トリガー時刻を表示
systemctl list-timers
systemctl list-timers --all            # 無効なものも含む

管理

# 起動/停止/再起動
systemctl start nginx
systemctl stop nginx
systemctl restart nginx                # プロセスは一時的に中断される
systemctl reload nginx                 # 再起動なしで設定を反映(サービス側で対応が必要、例: nginx -s reload)
# 違い: reload は接続を中断しないが、restart は中断する
# サービスが reload をサポートしていない場合、このコマンドは失敗する

systemctl enable nginx                 # 起動時に自動起動(シンボリックリンクを作成)
systemctl disable nginx                # 起動時の自動起動を無効化
systemctl reenable nginx               # 無効化してから再度有効化(壊れたシンボリックリンクを修復)

systemctl mask nginx                   # 起動を完全に禁止(シンボリックリンクを /dev/null に張る)
systemctl unmask nginx                 # 無効化を解除
# mask と disable の違い: disable 後は手動で start 可能だが、mask 後は手動での start も拒否される

# ユニットファイルを変更した後に必ず実行
systemctl daemon-reload                # 全ユニットファイルを再読み込み

# failed ステータスをクリア(しないと status で常に failed と表示される)
systemctl reset-failed nginx

ユーザーレベルサービス

# ユーザーサービスはシステムサービスとは独立している: ~/.config/systemd/user/
# ユーザーがログアウトするとデフォルトで停止する(lingering を有効にするまで)
systemctl --user status myservice
systemctl --user start myservice
systemctl --user enable myservice

# lingering を有効化(ログアウト後もサービスを継続して実行):
loginctl enable-linger <username>
# 用途: rathole-watchdog, ローカルの llama-server など、常駐が必要なユーザーサービス

Timer

Timer は指定された時間に対応する service をトリガーします(同名の .timer/.service ペアを使用):

# timer の定義を確認
systemctl cat mytask.timer

# 手動でトリガー(次回の待ち時間なし)
systemctl start mytask.service         # service を直接実行。timer には影響しない
# /etc/systemd/system/mytask.timer
[Timer]
# 前回アクティブ化後、5分ごとにトリガー
OnUnitActiveSec=5min
# 起動後、2分後に初回トリガー
OnBootSec=2min
# ランダムな遅延30秒(多数のサーバーが同時に実行するのを防ぐ — サンダリングハーデ現象対策)
RandomizedDelaySec=30
# 見逃したトリガーを補完(例: サーバーがスリープしていた場合)
Persistent=true

[Install]
WantedBy=timers.target
# /etc/systemd/system/mytask.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mytask.sh
User=myuser

ログ

journalctl -u nginx                     # 指定したユニットの全ログ
journalctl -u nginx -f                  # フォロー(tail -f と同様)
journalctl -u nginx --since "10 min ago"
journalctl -u nginx --since "2025-01-01" --until "2025-01-02"
journalctl -u nginx -n 50               # 最後の50行
journalctl -u nginx -o json-pretty | head -100  # 構造化出力(PID, UID, cmdline を含む)

journalctl -b                           # 現在の起動セッションのログ
journalctl -b -1                        # 前回の起動セッションのログ(再起動前の問題調査に)

journalctl _PID=12345                   # PID でフィルタリング

# スペース管理
journalctl --disk-usage                  # 現在の使用量
journalctl --vacuum-size=500M            # 最大500MBに制限
journalctl --vacuum-time=7d              # 過去7日間のログを保持

Override

ユニット設定を変更する場合、/usr/lib/systemd/system/ を直接編集するのではなく、drop-in を作成してください(パッケージ管理で上書きされるため):

# エディタを開いて override を作成
systemctl edit nginx
# → /etc/systemd/system/nginx.service.d/override.conf

# または手動で作成
mkdir -p /etc/systemd/system/nginx.service.d
cat > /etc/systemd/system/nginx.service.d/override.conf <<EOF
[Service]
# 環境変数を追加
Environment=DEBUG=true
# 起動コマンドを変更(まず空にしてから新しい値を設定)
ExecStart=
ExecStart=/usr/bin/nginx -g "daemon off;"
# 再起動ポリシーを設定
Restart=on-failure
RestartSec=5s
EOF
systemctl daemon-reload
systemctl restart nginx

ExecStart= の最初の行による空欄設定は必須です。先に空欄にしないと、新しい ExecStart は追加ではなく上書きされません。

トラブルシューティング

# サービスが起動しない場合
systemctl status nginx                  # Active: failed と終了コードを確認
journalctl -u nginx -e --no-pager      # 最後の1000行(stderr を確認)

# 起動のボトルネックを分析
systemd-analyze blame | head -20        # 各ユニットの初期化にかかった時間
systemd-analyze critical-chain nginx    # 依存チェーンのどの部分が最も遅いか

# ユニットファイルを検証
systemd-analyze verify /etc/systemd/system/myservice.service

# 特定のユニットが mask されているため WantedBy が無効になっている場合
ls -la /etc/systemd/system/*.target.wants/ | grep /dev/null