シングルパスのボトルネック
TCPは1970年代からウェブを支えてきましたが、よりシンプルな時代のために構築されました。その最大の欠点は何でしょうか?それは、接続が正確に2つのIPアドレスにハードコードされていることです。サーバーに2つの10GbEファイバーリンクがあると想像してください。両方が接続されていても、標準のTCPは2番目のパスを完全に無視します。技術者が誤ってアクティブなケーブルを抜いてしまうと、隣に完璧な10Gbpsのバックアップがあるにもかかわらず、セッションは即座に終了してしまいます。
管理者がIPの手動切り替えや複雑なアプリケーションの再試行でこれを解決しようとするのをよく見かけますが、それらは単なる応急処置に過ぎません。本当の問題は、トランスポート層が余分なハードウェアを認識していないことです。これにより、膨大な帯域幅が放置され、エッジコンピューティングやデータセンターの同期のような重要な環境において接続が脆弱になります。
なぜ標準TCPは複数リンクで失敗するのか
その理由は、TCPの4タプル(送信元IP、送信元ポート、宛先IP、宛先ポート)に集約されます。最初のハンドシェイクが完了すると、これら4つの要素はロックされます。オフィスを出てスマートフォンの接続がWi-Fiから5Gに切り替わると、送信元IPが変わります。すると4タプルが崩れ、サーバーは新しいIPを既存のセッションの一部として認識できないため、接続を切断します。
マルチパスTCP (MPTCP) は、単一の接続が異なるインターフェースを介して複数の「サブフロー」を管理できるようにすることで、この問題を解決します。論理セッションを物理的な配線から切り離すのです。これにより、2つのイーサネットポートを使用している場合でも、ファイバーと衛星通信を組み合わせている場合でも、利用可能なすべてのパスにデータを同時に分散(ストライプ化)させることができます。
MPTCP vs. リンクアグリゲーション (LACP)
エンジニアはしばしばMPTCPをイーサネットボンディングやLACPと混同します。これらは一見似ていますが、解決する問題が異なります。
- 標準TCP: 1つのパスを使用します。そのパスが失敗すると、接続は切断されます。速度は、最も速い単一のインターフェースの速度に制限されます。
- LACP (レイヤー2 ボンディング): 物理リンクを1つの論理パイプに統合します。通常、専用のスイッチハードウェアが必要であり、パスの遅延が異なったり、異なるルーターを経由したりする場合に苦労します。
- MPTCP (レイヤー4): 完全に異なるネットワーク間でも機能します。安定した1GbpsのISPリンクと150Mbpsの5Gモデムを組み合わせることも可能です。MPTCPは各パスの輻輳を独立して管理し、宛先でのパケット再構成を処理します。
私の経験では、アップストリームのスイッチを制御できないが、100%の稼働率が必要なモバイルゲートウェイにおいて、MPTCPは優れた選択肢となります。
トレードオフ:MPTCPには価値があるか?
メリット
- 真のスループット統合: 100Mbpsのリンクが2つあれば、MPTCPは単一の50GBファイル転送をほぼ200Mbpsで実行できます。
- ダウンタイムゼロのフェイルオーバー: プライマリ回線が切断されても、サブフローは削除されますが、メインの接続はバックアップで維持されます。ユーザーは瞬きする間も気づかないでしょう。
- インテリジェントな負荷分散: プライマリのファイバーが95%の容量に達したときだけ、安価で高遅延の衛星リンクを使用するといった運用が可能です。
課題
- ミドルボックスの干渉: 一部の厳格な企業ファイアウォールは、MPTCPヘッダーを「異常」と見なしてパケットを破棄することがあります。
- 最新のカーネルが必要: 現在はLinuxに組み込まれていますが、カーネル5.6以降が必要です。Ubuntu 18.04のような古い環境では、カスタムパッチが必要です。
- 処理コスト: 複数のストリームの管理やバッファの並べ替えにより、標準TCPと比較してわずかなCPUオーバーヘッドが発生します。
導入の前提条件
MPTCPの動作を確認するには、最新のスタックが必要です。Ubuntu 22.04やRHEL 9など、カーネル5.15以降を搭載したディストリビューションを使用してください。重要なのは、クライアントとサーバーの両方がプロトコルをサポートしている必要がある点です。サーバーがMPTCPに対応していない場合、接続は単に標準TCPにフォールバックします。このフェイルセーフにより、効率化を試みることで接続性が失われることはありません。
LinuxでのMPTCPの設定
実装は非常に簡単です。主要な処理はすでにメインラインカーネルに含まれているため、すべてをゼロからコンパイルする必要はもうありません。
1. カーネルのサポートを確認する
以下のコマンドを実行して、カーネルにMPTCPモジュールが含まれていることを確認します:
grep -i MPTCP /boot/config-$(uname -r)
CONFIG_MPTCP=yを探してください。次に、ランタイムでプロトコルが有効であることを確認します:
sysctl net.mptcp.enabled
net.mptcp.enabled = 1と表示されれば、エンジンの準備は整っています。
2. 制御ツールのインストール
iproute2パッケージのip mptcpコマンドを使用します。最近のほとんどのディストリビューションではデフォルトでインストールされていますが、念のため更新しておきましょう。
sudo apt update && sudo apt install iproute2 -y
3. 接続制限の設定
デフォルトでは、カーネルは追加のサブフローを0に制限している場合があります。システムが複数のパスを使用できるように許可する必要があります。インターフェースが2つある場合は、制限を少なくとも2に設定してください。
# 1接続あたりの最大サブフロー数を2に設定
sudo ip mptcp limits set subflow 2
# 新しいパスの着信要求を受け入れるように設定
sudo ip mptcp limits set add_addr_accepted 2
4. インターフェースのマッピング
ip addrでIPを確認します。例えば、eth0が192.168.1.10、eth1が192.168.2.10であるとします。これらをMPTCP対応としてフラグを立てる必要があります。
# eth0をマークして、相手側にその存在を通知する
sudo ip mptcp endpoint add 192.168.1.10 dev eth0 signal
# eth1をマークして、新しいサブフローの開始を許可する
sudo ip mptcp endpoint add 192.168.2.10 dev eth1 subflow
signalフラグはサーバーに「利用可能な別のIPがある」と伝えます。subflowフラグはクライアントに「この特定のインターフェースを使用して2番目のパスを開始せよ」と伝えます。
5. ルーティング競合の修正
よくある悩みとして、Linuxがeth1のパスのパケットをeth0のゲートウェイ経由で送信しようとすることがあります。これはすべてを台無しにします。ポリシールーティングを使用して、トラフィックが正しい配線に留まるようにしてください。
# eth1のIPからのトラフィックを独自のテーブル経由でルーティングする
sudo ip rule add from 192.168.2.10 table 100
sudo ip route add default via 192.168.2.1 dev eth1 table 100
6. 検証
ss(ソケット統計)を使用して作業内容を確認します。MPTCPが有効なサーバーに接続し、以下を実行します:
ss -nliM
-Mフラグにより、MPTCPの内部情報が表示されます。複数のサブフローがリストされているはずです。本格的なストレステストを行うには、5GBのダウンロードを開始し、プライマリインターフェースを無効にしてみてください:
sudo ip link set eth0 down
正しく設定されていれば、ダウンロードは一時停止することなく続行されます。この回復力こそが、MPTCPが高可用性Linuxネットワークのゴールドスタンダードになりつつある理由です。

