MTU、ジャンボフレーム、MSSクランピングの最適化:Linuxでのネットワーク遅延やラグを解消する「秘策」

Network tutorial - IT technology blog
Network tutorial - IT technology blog

「トラック」の例えと謎のネットワーク遅延の物語

かつて、約50名のスタッフ向けのストレージサービスを運用するデータセンターを管理していた時のことです。ある時期、社内Webへのアクセスが極端に遅いという苦情が出始めました。さらに、サーバーにSSHで接続すると、画面が頻繁にフリーズしてしまいます。不思議なことに、iperf3で測定すると帯域幅は1Gbps近くあり、レイテンシ(遅延)もわずか1〜2msでした。

調査の結果、問題は回線ではなくパケットサイズにあることが分かりました。データをトンネルを通るトラックに例えてみましょう。トラックが高すぎ(大きなパケット)、トンネルが低い(中継機器のMTUが小さい)場合、トラックは一度止まって荷物を小さなトラックに積み替えなければなりません(Fragmentation)。最悪の場合、トラックが詰まってしまい、パケットロス(Packet loss)が発生します。MTU、ジャンボフレーム(Jumbo Frames)、MSSクランピングの設定は、あらゆる道路に適した「トラック」のサイズを再設計することなのです。

なぜパケットの「断片化」(Fragmentation)は致命的なのか?

ネットワークの世界では、1500バイトがMTU(Maximum Transmission Unit)の標準的な数値です。10MBのファイルは、送信時に何千もの1500バイトのパケットに分割されます。

問題は、これらのパケットがVPNやPPPoEのような、より「細い管」を通る時に発生します. これらの接続は、カプセル化のヘッダーにスペースを割くため、通常1492バイトや1450バイトしか許可しません。この時、ルーターは強制的にフラグメンテーション(Fragmentation)を実行します。パケットを2つに分割して送信し、受信側でそれらを再構築する必要があります。このプロセスはルーターのCPUを消費し、レイテンシを2〜3倍に増加させます。多くの場合、パケットが完全にドロップされ、接続が99%のところで止まってしまう原因となります。

主要パラメータの理解:MTU、ジャンボフレーム、MSS

  • MTU (Maximum Transmission Unit): レイヤー2におけるデータフレームの最大サイズ。
  • MSS (Maximum Segment Size): TCPパケット内の実際のデータ(ペイロード)部分。通常, MTUから40バイトのヘッダー(IP 20バイト + TCP 20バイト)を引いたもの。MTU 1500の場合、理想的なMSSは1460。
  • Jumbo Frames: MTUが最大9000バイトに達するパケット。処理が必要なパケット数を減らせるため、大容量データのバックアップや内部ネットワークでのSAN運用に非常に効果的。

コマンド一つで最適なMTUを特定する方法

当てずっぽうはやめましょう。Linuxのpingコマンドで、-M do(断片化禁止)と-s(サイズ指定)オプションを使って、ネットワークの「限界点」を見つけます。

# 1472バイトでpingを試行(1472 + 28バイトのヘッダー = 1500)
ping -s 1472 -M do 8.8.8.8

もし Frag needed and DF set というメッセージが表示されたら、1500バイトでは大きすぎるということです。pingが成功するまで、1472の数値を徐々に下げて(例:1460、1450…)試してください。最適なMTUは、その数値に28を加えたものになります。

Linuxにおけるジャンボフレームの実践的な設定

インターフェース eth0 のMTUを即座に変更するには、ip コマンドを使用します:

# 10Gbpsの内部ネットワーク用にMTU 9000を設定
sudo ip link set dev eth0 mtu 9000

# 結果を確認
ip link show eth0

極めて重要な注意点: ジャンボフレームを有効にする場合、スイッチからサーバーまで、すべてのデバイスの設定を9000に同期させる必要があります。1つでも1500しかサポートしていない箇所があると、9000バイトのパケットはすべてドロップされ、システム全体の通信が遮断されます。

Ubuntuで再起動後も設定を維持するには、/etc/netplan/ にある Netplan ファイルを編集します:

network:
  version: 2
  ethernets:
    eth0:
      mtu: 9000
      dhcp4: true

その後、次のコマンドで適用します:sudo netplan apply

MSS Clamping: VPNのための救済策

クライアント側のMTUを操作できないケースも多々あります。例えば、従業員がWireGuard VPNを使用してサーバーにアクセスしている際、Webサイトのタイトルだけ表示されて止まってしまうような場合です。ここでMSSクランピング(MSS Clamping)が威力を発揮します。各端末を設定する代わりに、Linuxルーター/ゲートウェイ側で直接設定を行います。

これはTCPのハンドシェイク(3-way handshake)プロセスに介入し、MSSサイズを安全なレベルに強制的に下げます。iptables を次のように使用します:

# インターフェースの実際のMTUに合わせてMSSを自動調整
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# または、絶対的な安全のために1400バイトに固定
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400

この手法は、VPNやプロバイダーの光回線を使用している際に発生する「Webサイトが読み込み中のまま進まない」問題の90%を解決します。

実戦経験:いつ最適化すべきか?

長年のインフラ運用の経験から、3つの核心的なルールを導き出しました:

  1. 公衆インターネット: MTUを1500以上に上げるのは厳禁です。インターネット上のルーターが即座にパケットをドロップします。ゲートウェイを構築する場合は、MSSクランピングを使用してください。
  2. バックアップ/ストレージシステム: ジャンボフレーム(MTU 9000)を有効にしましょう。実際のテストでは、CPU負荷を15%から5%に低減し、ファイルコピー速度を約15%向上させることができました。
  3. ICMPをブロックしない: ファイアウォールで ICMP Type 3 Code 4 をブロックしないようにしてください。これをブロックすると、LinuxのMTU自動探索機能(PMTUD)が動作しなくなり、デバッグが非常に困難な「ブラックホールルーター」問題が発生します。

まとめ

あらゆるシナリオに完璧なMTU設定というものはありません。私のアドバイスは、インターネットには1500を維持し、内部ストレージには9000を使用し、VPNには常にMSSクランピングを準備しておくことです。パケットがどのように移動するかを理解することで、暗闇の中で解決策を探すのではなく、自信を持ってネットワークトラブルに対処できるようになります。

Share: