【テクニカル・上級編】 tcpdumpによるスナップショット長(-s)とバッファあふれ対策 – トラブルシューティング&ネットワーク運用監視実践ガイド

tcpdumpの深淵:パケットドロップを許さない、高負荷環境の「真実」を切り取る技術

ネットワークエンジニアにとって、tcpdumpは最後の砦だ。しかし、真夜中のデータセンターで、10Gbpsを超えるトラフィックが流れるリンクを前にしたとき、あなたは「なんとなく」コマンドを打っていないだろうか?

「パケットが消えた」と騒ぐ現場で、実はキャプチャツール自体が悲鳴を上げてパケットを捨てている。そんな恥ずべき事態を避けるために、今日はtcpdumpにおけるスナップショット長(snaplen)の最適化と、カーネルレベルのバッファリングについて、現場の泥臭い知見を共有する。

なぜ「デフォルト」ではいけないのか

tcpdumpのデフォルトのsnaplenは、多くの環境で 68 または 96 バイト程度だ。これはEthernetフレームのヘッダーとIP、TCPヘッダーを拾うには十分だが、昨今のモダンなアプリケーション解析にはあまりに心許ない。

もし君が、TLSのClient Helloに含まれるSNI(Server Name Indication)を確認したり、HTTP/2のヘッダー圧縮(HPACK)の挙動を追うのであれば、この設定は致命的だ。パケットのペイロードまで含めてキャプチャしようとしてsnaplenを0(無制限)にするエンジニアもいるが、高トラフィック環境ではそれが「自爆スイッチ」になる。

スナップショット長とパフォーマンスのトレードオフ

snaplenを広げれば、それだけカーネルからユーザースペースへのコピーコストが増大する。特にパケットレートが高い環境では、CPUの割り込み処理が飽和し、キャプチャそのものがボトルネックとなって、本来追うべき障害の痕跡すら消し去ってしまう。

現場では、「必要な情報を、最小限のコストで抜く」のがプロの流儀だ。

# ヘッダー解析に特化する場合(80-128バイト程度で十分なケースが多い)
# -s 128: Ethernet(14) + IP(20) + TCP(20) + オプション + ペイロードの先頭部分
tcpdump -i eth0 -s 128 -w capture.pcap 'tcp port 443'

TLSハンドシェイクのログを取りたい場合は、128バイトでは足りない。SNIまで見たいなら、最低でも256バイト程度は確保しておくと安心だ。

高トラフィック環境の敵:バッファあふれを制する

高負荷なリンクでtcpdumpを動かすと、dropped by kernelという冷徹なメッセージが画面を流れることがある。これは、カーネルがパケットをtcpdumpのリングバッファにコピーする速度よりも、NICがパケットを受信する速度が上回ったときに発生する。

これを防ぐための最大の武器が -B(バッファサイズ)オプションだ。

Linuxカーネルのリングバッファを拡張せよ

デフォルトのバッファサイズでは、数ミリ秒のバーストトラフィックに耐えられない。現場では、最低でも128MB、高負荷なら256MB以上を割り当てるのが定石だ。

# バッファを256MBに拡張し、スナップショット長をTLS解析用に適正化
# -B 262144: 256MBのバッファを確保
# -n: 名前解決を無効化(DNS遅延によるキャプチャ漏れを防ぐ)
tcpdump -i eth0 -n -s 256 -B 262144 -w investigation.pcap 'host 10.0.1.5 and tcp port 443'

もしこれでもパケットが落ちるなら、tcpdumpの実行プロセスがCPUコアを占有できていない可能性がある。tasksetを使って、当該NICの割り込み処理が行われているCPUコアと、tcpdumpプロセスを同じNUMAノード上に固定してやるだけで、劇的にドロップ率は改善する。

なぜ「ヘッダーだけ」にこだわるのか

インフラアーキテクトとして、我々が真に注目すべきは「パケットの中身」ではない。パケットが刻む「時間」と「順序」だ。

  • RTT(Round Trip Time)の計測: SYNを送ってからSYN-ACKが返るまでの時間。ここをtcpdumpで正確に追いかける際、snaplenが大きすぎると、カーネルがパケットを処理するまでの「ジッター(揺らぎ)」が計測結果に混入する。
  • TLSハンドシェイクの最適化: セッション再開(Session Resumption)のパケットを解析する際、余計なペイロードはノイズでしかない。

ヘッダー情報さえあれば、Wireshark(tshark)の統計機能を使って、TCPのウィンドウサイズ推移や、再送発生のトリガーを論理的に特定できる。

現場の知恵:運用監視への落とし込み

最後に、本番環境で運用中のエンジニアへアドバイスを一つ。tcpdumpを長時間回し続けるのはNGだ。ディスクのI/O負荷がシステム全体を巻き込む。

もし継続的な監視が必要なら、tcpdumpではなくeBPFベースのツール(tcptopやbiolatencyなど)への移行を検討すべきだ。しかし、障害が起きた「その瞬間」を切り取るためのtcpdumpの作法は、今後も変わらない。

1. -n を忘れるな: 現場で名前解決待ちが発生すると、キャプチャの整合性が崩れる。
2. フィルタを極限まで絞れ: host、port、tcp-synなどのフラグを組み合わせ、不要なトラフィックをカーネル側で捨てさせる。
3. -B でゆとりを持て: メモリをケチるな。パケットが落ちて原因が特定できないコストに比べれば、数百MBのメモリなど安いものだ。

ネットワークは生き物だ。その挙動をパケットレベルで正確に観測できるエンジニアだけが、複雑怪奇な分散システムのトラブルを沈静化できる。さあ、次は君の番だ。ターミナルを開き、コマンドに魂を込めろ。

コメント

タイトルとURLをコピーしました