「プロセス数が増え続けている」「特定サービスが止まらない」——そういった障害の一次切り分けで、まず確認したいのがプロセスの親子構造です。どのプロセスが何を生み出しているかを素早く把握できれば、原因の特定と対処が格段に速くなります。
プロセスの親子構造を把握すべき場面
プロセスの親子関係が障害切り分けで役立つ場面は、主に以下の3つです。
- サービスが停止できない — 子プロセスが残っているため、親を落としても再起動できない
- プロセスが異常増殖している — フォーク爆弾やリクエスト過多による子プロセスの際限ない生成
- 不審なプロセスが動いている — 誰が生んだか不明なプロセスの親をたどって侵害範囲を確認する
いずれも「このプロセスの親は何か」「このサービスは何プロセスを抱えているか」を即座に確認できるかどうかで、対応速度が変わります。
プロセス全体をツリー表示で俯瞰する
まず pstree で全体像を把握します。systemd 世代のサーバーでは、ルートは init ではなく systemd(PID 1)です。Ubuntu 20.04以降・RHEL/AlmaLinux 8以降・Debian 10以降はすべてこの構成です。
# PID付きでプロセスツリーを表示する
pstree -p
# 特定ユーザーのプロセスだけに絞る(www-data の例)
pstree -p www-data
# スレッドも展開して表示する
pstree -pt
実行例(Ubuntu 24.04 / AlmaLinux 9 など systemd 環境):
systemd(1)─┬─ModemManager(812)───2*[{ModemManager}]
├─NetworkManager(893)───2*[{NetworkManager}]
├─apache2(1201)─┬─apache2(1248)
│ ├─apache2(1249)
│ └─8*[apache2]
├─mysqld(1354)───28*[{mysqld}]
└─sshd(925)───sshd(2031)───sshd(2033)───bash(2034)───pstree(3102)
括弧内がPIDです。apache2 が10プロセスを抱えているなど、サービスの規模感が一目でわかります。sshd から bash まで繋がっている部分が、現在ログイン中のセッションです。波括弧で囲まれた {mysqld} はスレッドを示します。
CPU使用率やメモリ情報も合わせて確認したい場合は ps auxf が有効です。
# ツリー形式で全プロセスを詳細表示
ps auxf
# 特定サービスに絞って確認(apache2 の例)
ps auxf | grep -A 20 '[a]pache2'
USER PID %CPU %MEM STAT COMMAND
root 1201 0.0 0.1 Ss /usr/sbin/apache2 -k start
www-data 1248 0.0 0.0 S \_ /usr/sbin/apache2 -k start
www-data 1249 0.0 0.0 S \_ /usr/sbin/apache2 -k start
\_ がインデントされるほど深い子孫プロセスです。STAT列が Z のプロセスはゾンビ状態(親が回収していない)を示します。
サービス単位でプロセスを絞り込む(systemd 時代の実務)
systemd 環境では、systemctl status が最も手軽なサービスごとのプロセス確認手段です。
systemctl status apache2
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled)
Active: active (running) since Thu 2026-08-06 09:00:00 JST
Main PID: 1201 (apache2)
Tasks: 11 (limit: 4915)
Memory: 32.5M
CPU: 2.341s
CGroup: /system.slice/apache2.service
├─1201 /usr/sbin/apache2 -k start
├─1248 /usr/sbin/apache2 -k start
└─1249 /usr/sbin/apache2 -k start
CGroup セクションに表示されるプロセスが、このサービスが管理している全プロセスです。ここに表示されないプロセスは systemd の管理外であることを意味します。サーバー全体のサービスとプロセスの対応を一覧したい場合は systemd-cgls が便利です。
# cgroup ツリー全体を表示する
systemd-cgls
# 特定サービスのみ確認する
systemd-cgls /system.slice/apache2.service
Control group /:
└─system.slice
├─apache2.service
│ ├─1201 /usr/sbin/apache2 -k start
│ ├─1248 /usr/sbin/apache2 -k start
│ └─1249 /usr/sbin/apache2 -k start
├─mysql.service
│ └─1354 /usr/sbin/mysqld
└─sshd.service
└─925 /usr/sbin/sshd -D [listener] 0 of 10-100 startups
コンテナ環境(Docker / LXC)が混在するホストでは、systemd-cgls のほうが pstree より実態に近い階層を示します。
実務でよく使う異常検知パターン
ゾンビプロセスを検出する
# STAT が Z のプロセスを抽出する
ps aux | awk '$8 == "Z" {print}'
# ゾンビの親PIDも合わせて確認する
ps -eo pid,ppid,stat,comm | awk '$3 ~ /Z/ {print}'
ゾンビプロセス自体は即時の害はありませんが、大量発生はアプリケーションのバグを示します。PIDを使い切るリスクもあるため、親プロセスの再起動か修正が必要です。
不審な親子関係を特定する
# 特定のPIDを親に持つ子プロセスを確認する(例: PPID=1354)
ps --ppid 1354
# pstree で特定PIDのサブツリーだけを表示する
pstree -p 1354
ある運用現場では、sshd 配下に見慣れない bash が常時起動しているのを pstree -p で発見し、不正ログインを早期に検知したケースがありました。親子関係の「違和感」は、目視での発見が有効です。
プロセス数の変化をリアルタイムで追う
# Webサーバーのワーカー数を2秒ごとに監視する
watch -n 2 'ps auxf | grep -c "[a]pache2"'
# systemd 管理下のタスク数(スレッド含む)を確認する
systemctl status apache2 | grep Tasks
watch と組み合わせることで、プロセス数の変化を継続的に追えます。高負荷時のワーカー急増や、リクエスト処理後に子プロセスが回収されない状態の検出に役立ちます。
systemd 環境でプロセスを止める際の注意点
systemd 環境では、プロセスは cgroup でグループ化されて管理されています。個別のPIDに kill -9 を使うと、子プロセスが残ったり systemd が自動再起動したりする場合があります。サービスごとクリーンに止めたい場合は systemctl kill を使います。
# サービス配下の全プロセスに SIGTERM を送る(推奨)
sudo systemctl kill apache2
# 即時強制終了が必要な場合(SIGKILL)
sudo systemctl kill -s SIGKILL apache2
# 完全停止(cgroup ごと終了 + 自動再起動も止める)
sudo systemctl stop apache2
systemctl kill は cgroup 配下の全プロセスにシグナルを一括送信します。個別PIDへの kill は、子プロセスが取りこぼされるリスクがあるため、特別な理由がない限り避けるのが安全です。プロセス構造の把握と停止操作をセットで身につけることで、障害対応の確実性が上がります。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
