現場のエンジニアが「見えない敵」を撃つとき:ssコマンドでソケットを追跡する流儀
深夜2時、アラートが鳴り響く。監視画面には「APIエンドポイントが応答なし」の無慈悲な表示。現場で数多の修羅場をくぐり抜けてきた身から言わせれば、ここで焦って再起動をかけるのは素人のやることだ。
まずやるべきは、現場の「状況把握」。ネットワークが疎通しているのか、そもそもアプリケーションがポートを掴んでいるのか。今日は、そんな泥臭い現場で最も頼りになる相棒、ssコマンドを用いたポートとプロセスの紐付け手法について語ろうと思う。
なぜ今、netstatではなくssなのか
古参のエンジニアなら「netstatでいいじゃないか」と言うかもしれない。だが、現代のLinux環境において、netstatはすでにレガシーな存在だ。netstatは /proc/net/ 以下を直接舐めるため、接続数が膨大になると極端に処理が重くなる。
対して ss (Socket Statistics) は、カーネル内部の netlink ソケットを直接叩く。爆速であり、かつ情報量も圧倒的だ。我々のように数万単位の接続を捌くバックエンドの現場では、もはやss一択である。
「犯人」を特定する魔法のコマンド
障害時に真っ先に打つべきコマンドはこれだ。
# 権限昇格して、リスニング中のプロセスをPID付きで特定する
$ sudo ss -tulpn
このコマンドのオプションには、現場の知恵が詰まっている。
-t(TCP): 焦っている時ほどUDPのノイズは見たくない。TCPに絞る。-u(UDP): 必要に応じて。-l(Listening): 「どこで待ち受けているか」を知るための必須オプション。-p(Processes): ここが肝だ。 どのPIDがそのポートを占有しているかを暴く。-n(Numeric): ホスト名解決で時間を浪費するな。IPとポート番号をダイレクトに表示させろ。
これらを組み合わせれば、以下のような出力が得られるはずだ。
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("python3",pid=1234,fd=3))
これで「8080番ポートで待ち受けているのは、PID 1234のPythonプロセスだ」と即座に特定できる。ps -ef | grep 1234 でそのプロセスの正体を追えば、障害の全貌が見えてくるというわけだ。
実践:Web APIが「Address already in use」と泣くとき
インフラ構築時によくあるのが、ポートの競合だ。開発中のAPIサーバーが 8080 を掴んだまま終了できず、再起動時にエラーを吐く。
# APIサーバーの起動コード例(Flaskなど)
from flask import Flask
app = Flask(__name__)
@app.route('/health')
def health():
return "OK", 200
if __name__ == '__main__':
# 実際にはここでポートの競合が起きると起動しない
app.run(host='0.0.0.0', port=8080)
この時、ss -tulpn を叩いてみると、前回のゾンビプロセスがポートを死守しているのが見える。この瞬間、君は「ポートを解放できないプログラム」を修正するか、kill -9 で強制排除するかの選択を迫られる。これがトラブルシューティングの醍醐味だ。
トラブルの連鎖を断ち切るために
APIが疎通しない原因は、必ずしもポートが開いていないことだけではない。ss を使って確認すべきは「Local Addressが何になっているか」だ。
0.0.0.0:8080: 全インターフェースで待ち受けている。正常。127.0.0.1:8080: ローカルホストからしかアクセスできない。これこそが、外部からAPIが繋がらない原因の第1位だ。
コンテナ環境で nginx や Python がローカルループバックにバインドしてしまい、外部からのリクエストを弾いていることは珍しくない。設定ファイルを書き換える前に、まず ss でこの「待ち受けアドレス」を確認する癖をつけてほしい。
最後に:コマンドは「問いかけ」である
僕が後輩に口酸っぱく言うのは、「コマンドはただの道具ではなく、システムへの問いかけだ」ということだ。
ss -tulpn は、システムに対して「今、誰がどの扉を開いて待ち構えているんだ?」と問いかける行為である。その問いかけに対する答えを読み解き、プロセスの動きを頭の中でフローチャート化できるようになった時、君はもう初心者ではない。
ネットワークは生き物だ。パケットの奔流の中に、設計者の意図と、今の運用の歪みが混ざり合っている。その歪みを、ss という鋭利なメスで切り分け、最短距離で障害を鎮圧する。それこそが、我々エンジニアの誇りだと僕は信じている。
さあ、次のアラートが鳴る前に、手元のターミナルで ss を叩いておこう。未知のポートを紐解く準備はいいか?
コメント