ネットワークの深淵を覗く:MTUの不一致と「静かなるパケットロス」の正体
大規模データセンターの運用現場において、最も神経を尖らせるのは「なぜか特定の通信だけが通らない」という怪奇現象だ。コネクションは確立しているのに、ペイロードが乗った瞬間にプッツリと切れる。ログを追いかけてもルーターのCPU負荷は正常。この手のトラブルの犯人は、9割方 MTU(Maximum Transmission Unit)の不一致と DF(Don’t Fragment)ビットの衝突にある。
今日は、教科書的な説明は抜きにして、なぜパケットが「断片化を拒絶」するのか、そして現場でどうやってこの「不可視の壁」を突破すべきか、その深淵を共有しよう。
—
1. パケットが「死」を選ぶ理由:DFビットの役割
我々が日々叩く ping コマンド。これに -M do オプションをつけてパケットを飛ばしたことはあるだろうか。これは、IPヘッダーにある DF (Don’t Fragment) フラグを強制的に立てるスイッチだ。
# サイズ1472バイトのペイロード + 28バイトのヘッダー = 1500バイトで送信
# DFビットをセットし、断片化を許可しない
ping -M do -s 1472 192.168.1.1
なぜわざわざ「断片化するな」と命令するのか。それは、現代の高速ネットワークにおいて、ルーターによるパケットの断片化(Fragment)は「悪」だからだ。断片化が発生すると、ルーターのCPUはパケットを再構築するために膨大な演算コストを払う。さらに、断片化されたパケットの一部が欠損すれば、受信側は再送を待つ必要があり、遅延(Latency)は跳ね上がる。
だからこそ、TCP/IPのスタックは「断片化されるくらいなら、最初から送るな」と判断する。これが PMTUD (Path MTU Discovery) の本質だ。
—
2. 現場のトラップ:ICMP到達不能メッセージの行方
PMTUDは、経路上のどこかでMTUサイズを超過したとき、ルーターが「Destination Unreachable (Fragmentation Needed)」という ICMP Type 3, Code 4 を送信元に返すことで成立する。
しかし、セキュリティ対策と称してネットワーク境界で ICMP を全拒否(DROP)している環境が多すぎる。結果、送信側は「パケットが届かなかったのか、拒否されたのか、それともMTUオーバーなのか」を判断できず、沈黙したまま再送を繰り返し、タイムアウトを迎える。これが、TLSハンドシェイクが始まるところで止まるという、あの「地獄の現象」の正体だ。
—
3. 実践:トランスポート層を最適化する「攻め」のMTU探索
インフラアーキテクトとして知っておくべきは、単なる疎通確認だけではない。TCPの MSS (Maximum Segment Size) は、MTUからIPヘッダー(20bytes)とTCPヘッダー(20bytes)を引いた値だ。
もしあなたのシステムが VXLAN や IPsec を多用するオーバーレイネットワーク上にあるなら、ヘッダーオーバーヘッド分を考慮してMTUを意図的に下げる必要がある。
MSSを強制調整する(iptablesの例)
パケットのヘッダーを書き換えて、ネゴシエーション時に強制的に小さなパケットを強いる手法だ。
# 経路のMTUが1400と判明している場合、TCPハンドシェイクでMSSを1360に絞る
# 20(IP) + 20(TCP) = 40バイト分を差し引く
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --set-mss 1360 # 通信の安定性を確保するための苦肉の策
—
4. パフォーマンスチューニングへの応用:バッファとウィンドウ
MTUの最適化は、TCPウィンドウサイズ とのセットで考えるべきだ。MTUが物理的な「一度に運べる荷物のサイズ」なら、TCPウィンドウは「一度に受け取れる荷物の量」である。
sysctl で設定する際、以下の値を意識したことはあるだろうか。
# ネットワーク帯域が太く、RTTが大きい場合の設定
# 16MB程度のバッファを確保してスループットを維持する
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# パケットロス耐性を高めるためのキュー長調整
net.core.netdev_max_backlog = 5000
これらのチューニングを施した上で、再度 ping を使ってエンドツーエンドの PMTUD を確認する。もし特定のサイズを超えるとパケットが落ちるなら、経路のどこかに VPN 装置や クラウドゲートウェイ が潜んでいる。そこがボトルネックだ。
—
最後に:エンジニアが向き合うべき「リアル」
ネットワークのトラブルシューティングにおいて、コマンドは単なる道具に過ぎない。重要なのは、パケットがワイヤーの上をどう飛び、どのルーターで解釈され、どのタイミングで破棄されたのかという「ストーリー」を脳内でシミュレーションする力だ。
ping で送り出した1つのパケットの生死にこだわる。その執念こそが、大規模な基盤を支える技術者の矜持である。さあ、今日はどの経路を探索しようか? ネットワークの深淵は、意外とすぐ足元にあるものだ。
コメント