XDPとIPVSでQUIC用のロードバランサー実装

目次
はじめに
Webは常に進化しており、より高速で信頼性の高い接続が求められています。近年、従来のTCP/IP通信に比べて大幅な改善をもたらす革新的な技術として、QUICプロトコルが登場しました。QUICは輻輳制御、低レイテンシ、強化されたセキュリティなどの特徴を備えており、モダンなモバイルアプリケーションにとって魅力的な選択肢となっています。
しかし、強力な機能にはそれ相応の責任が伴います。QUICの採用が拡大する中、高トラフィックを効率的に管理することが極めて重要です。従来のロードバランシング手法は主にTCP/IP用に設計されているため、QUICのマルチプレクシング特性に対応しきれず、結果としてボトルネックが発生し、QUICの潜在能力を十分に引き出せない可能性があります。
本ブログでは、QUICロードバランシングの課題に踏み込み、XDP(eXpress Data Path)による「QUICステアリング」とIPVS(IP Virtual Server)によるダイレクトルーティングを活用した効率的なトラフィック分散のための強力なソリューションについて解説します。QUICロードバランシングの課題、XDPとIPVSがどのように連携するのか、このアプローチの利点、さらにはダイレクトルーティングの概念とその統合の可能性について詳しく見ていきます。
本ブログを読み終える頃には、XDP、IPVS、そして場合によってはダイレクトルーティングを活用した効率的なロードバランシングにより、QUICの可能性を最大限に引き出す方法を包括的に理解できるようになるでしょう。さあ、未来のQUICトラフィック管理の世界へ足を踏み入れましょう。
QUICロードバランシングの課題
従来のロードバランサーは、UDPベースのQUICを扱う際にいくつかの課題に直面します:
- 接続IDの難題:
QUICは接続マイグレーションを利用しており、クライアントとサーバーの両者が動的に接続IDを変更可能です。これにより、ロードバランサーが接続を一貫して追跡および管理する能力が損なわれ、接続の切断やトラフィック分散の不均衡を引き起こす可能性があります。
- NATの問題:
ネットワークアドレス変換(NAT)は、QUICロードバランシングをさらに複雑にします。NATデバイスの背後にあるクライアントがQUIC接続を確立する際、接続マイグレーション中にソースIPアドレスが変更されることがあります。これにより、一貫したソースIPアドレスに依存してクライアントを特定し、トラフィックを適切にルーティングするロードバランサーが混乱する可能性があります。
- 可視性の制限:
従来のロードバランサーは、通常トラフィック管理のために「4タプル」(ソースIP、ソースポート、宛先IP、宛先ポート)に依存しています。しかし、QUICはUDP上で動作するため、多くのロードバランサーはこれを単なるUDPトラフィックとして扱います。結果として、単一のQUIC接続内でマルチプレクスされたストリームの可視性が制限され、個々のデータストリームに基づく最適なトラフィック分散には4タプルのみでは不十分となる可能性があります。
QUIC接続IDとは何か、そしてなぜ重要なのか?
従来のTCP接続が識別のために4タプル(ソースIPアドレス、ソースポート、宛先IPアドレス、宛先ポート)に依存するのに対し、QUICは接続ID(CID)と呼ばれる一意の識別子を利用します。このCIDは、QUICパケットヘッダーに埋め込まれたランダムに生成された値です。
CIDは従来の4タプル方式に比べて以下の利点を提供します:
アドレス変更を超えた持続性:
CIDの大きな利点はその持続性にあります。NATなどにより変動する可能性のある4タプル内のソースIPアドレスとは異なり、CIDはQUIC接続のライフタイム全体で一定に保たれます。この持続性により、クライアントのIPアドレスが変更された場合でも、クライアントとサーバーはシームレスな接続を維持できます。
QUICプロトコルによれば、接続のライフサイクル中にCIDが複数回動的に更新される場合があっても、クライアントとサーバーは現在使用中のCIDについて合意を形成しており、この合意はQUIC接続のライフタイム全体で変わることはありません。
マルチプレクシングの効率性:
QUICは単一の接続内で複数のデータストリームをサポートするためにマルチプレクシングを前提に設計されています。CIDは、受信側(クライアントまたはサーバー)が着信パケットを効率的に識別し、適切なデータストリームへデマルチプレックスするために重要な役割を果たします。
セキュリティの向上:
CIDのランダムな性質により、攻撃者が特定のQUIC接続に属するパケットを予測または偽造することが困難になり、通信全体のセキュリティが強化されます。
従来の課題:NATの壁とQUIC接続の中断
多くのユーザーはネットワークアドレス変換(NAT)ゲートウェイを経由してインターネットに接続しています。これにより、クライアントはNATによって割り当てられたパブリックアドレスを用いて通信するため、実際のIPアドレスが隠蔽されます。この状況は、ソースIP、ソースポート、宛先IP、宛先ポートという4タプルにのみ依存する従来の手法では、QUICロードバランシングに対して大きな課題を生み出します。
問題の展開は以下の通りです:
初期ハンドシェイク:
NATでクライアントがサーバーとQUIC接続を確立します。QUICの詳細を認識していないロードバランサーは、4タプルを用いてトラフィックを実サーバー(仮にサーバー1と呼びます)に転送します。
安定な接続(NATバインディングが維持される限り):
4タプル(クライアントのソースポートを含む)が同一であり、NATバインディングが維持される限り、クライアントからのその後のトラフィックはサーバー1に引き続き転送されます。
NATバインディングの中断:
しかしながら、NATによるクライアントのソースポート割り当ては、以下の2つの理由により変更される可能性があります:
非アクティブなトラフィックによるタイムアウト:
接続が一定期間非アクティブな場合、NATがクライアントのソースポートを再割り当てし、4タプルが変更されます。
クライアントのネットワーク変更:
クライアントが別のネットワークに移動すると、新たなパブリックIPアドレスが割り当てられ、4タプルに再び影響を及ぼします。
ロードバランサーの誤ったルーティング:
QUICの特性を認識していない従来のロードバランサーは、変更された4タプルを新たな接続とみなし、クライアントのその後のトラフィックを別の実サーバー(仮にサーバー2と呼びます)に転送する可能性があります。
- 接続の喪失(QUICのアドレスマイグレーション機能にもかかわらず):
QUICにはアドレスマイグレーション機能があるにもかかわらず、このシナリオでは接続を維持できません。クライアントのソースIPおよび元々接続されていたサーバー(サーバー1)の両方が変更されるため、通信を継続することが不可能となります。
- 問題点:
この接続中断は、双方に以下のような悪影響を及ぼします:
- クライアント:
接続が喪失し、進行中の通信やデータ転送が中断される可能性があります。
- サーバー:
サーバー1は確立された接続とその関連アプリケーションの状態を失い、データ損失やサービスの中断を引き起こす可能性があります。
- クライアント:
ソリューション:XDP QUICステアリングとIPVSダイレクトルーティング
EMQは、IoTシナリオ向けのQUIC技術の先駆者として常に最前線に立ってきました。ここでは、上記の課題に対処するために、XDPを活用した「QUICステアリング」とIPVSによるダイレクトルーティングを組み合わせたQUICロードバランシングソリューションをご紹介します。本章では、このソリューションの技術的詳細について探ります。
デプロイメント概要
- 実サーバーの設定:
プール内の各実サーバーは、ローカルネットワークインターフェース(リンクローカルデバイス)に固有のVIP(仮想IP)アドレスを設定されています。このVIPは、クライアントのQUIC接続のターゲットアドレスとして機能します。
- IPVSダイレクトルーティング(DR)モード:
標準的なIPVSインスタンスはDR(ダイレクトルーティング)モードで動作します。このモードでは、IPVSがトラフィックディレクターとして機能し、あらかじめ定義されたルール(例:ラウンドロビン、最小接続数)に基づいて、VIP宛の着信QUICパケットを実サーバープール内に分散します。重要なのは、IPVSが実サーバーへ転送するパケットの宛先アドレスがVIPのままである点です。
- XDP QUICステアリングモジュール:
「QUICステアリング」と呼ばれるカスタムXDPモジュールが、各実サーバーの公開ネットワークインターフェースにインジェクトされます。このモジュールはネットワーク層で動作し、高性能なパケット処理機能を提供します。
XDP QUICステアリングの機能
XDP QUICステアリングモジュールは、実サーバーに設定されたVIPアドレス宛のすべての着信UDPパケットを傍受し、以下の処理を行います:
- パケット検査:
モジュールはUDPパケットヘッダーの内容を検査します。
- 接続IDの抽出:
重要な点として、パケットヘッダーからQUIC接続IDを抽出します。QUICパケットに埋め込まれたこの接続IDには、パケットを転送すべき特定の実サーバーを識別する情報が含まれています。
- パケットルーティング:
抽出された接続IDがローカル実サーバーと一致しない場合、XDPモジュールはパケットを直接操作する能力を活用し、接続IDにより識別された指定の実サーバーへパケットをルーティングします。なお、モジュールはパケットヘッダー内の宛先アドレス(VIPのまま)を変更しないため、IPVSはルーティングテーブルとヘルスチェックを正しく維持できます。
詳細なフロー
フロー1: ハンドシェイク中のリクエストおよびリターンパスの形成
リクエストおよびリターンパス:
ステップ | アクション | 送信元アドレス | 宛先アドレス | 備考 |
---|---|---|---|---|
1 | クライアントがQUIC Initial (CRYPTO) を送信 | Client Private | VIP | |
2 | NAT変換 | NAT GW Public | VIP | |
3 | LBがRSを選択 | NAT GW Public | VIP | LBは送信元アドレスのハッシュ値を使用 |
4 | サーバーがQUICハンドシェイクで応答 | VIP | NAT GW Public | サーバーはSCID(Source Connection ID)を割り当て、これにXDPステアリング用のサーバーIDが含まれる。サーバーはクライアントへDR(ダイレクトルート)を実施。 |
5 | NAT変換 | VIP | Client Private | リクエストパスとリターンパスが形成され、NAT GWはこのマッピングを記憶する。 |
6 | クライアントがQUICハンドシェイク(ACK) を送信 | Client Private | VIP | ステップ1を再利用 |
7 | NAT変換 | NAT GW Public | VIP | ステップ2を再利用。NAT GWはマッピングからルーティング情報を検索 |
8 | LBがRS1へ転送 | NAT GW Public | VIP | ステップ3を再利用 |
9 | ネットワークパスが形成 | クライアントとサーバーは以下のパスで通信を継続する: 1 → 2 → 3 → 4 → 5 |
フロー2: アドレスマイグレーション後のQUICステアリング
前提条件:クライアントが別のネットワークに移動するか、NAT再バインディングが発生し、クライアントのパブリックアドレスが変更された状態。
ステップ | アクション | 送信元アドレス | 宛先アドレス | 備考 |
---|---|---|---|---|
1 | クライアントがQUICパケットを送信 | Client Private | VIP | クライアントがネットワーク変更を検知し、新しいパスのプロービングを開始、または通常のQUICパケットを送信(どちらのシナリオも機能する)。パケットには、上記ハンドシェイクフローのステップ4で使用されたSCIDに相当するDCID(Destination Connection ID)が含まれる。 |
2 | NAT変換 | NAT GW Public 2 | VIP | パブリック側で、クライアントは新しいパブリックアドレスを取得。 |
3 | LBがRS 2を選択 | NAT GW Public 2 | VIP | LBは送信元アドレスのハッシュ値を計算し、RS 2を選択。 |
4 | XDP QUICステアリング | NAT GW Public 2 | VIP | ここでXDP QUICステアリングモジュールが動作。DCIDが別のホスト(RS 1)をターゲットとしていることを検出し、送信元および宛先アドレスを変更せずにパケットをRS1へリルートする。 |
5 | RS 1が新しいパスのプロービングを開始 | VIP | NAT GW Public 2 | RS 1上のXDP QUICステアリングモジュールは、UDPパケットがRS1宛であると検出し特に処理を行わない。RS 1のQUICスタックは、クライアントのアドレスが「NAT GW Public」から「NAT GW Public 2」に変更されたことを認識し、新しいパスのプロービングを開始する。 |
6 | NAT変換 | Client Private | VIP | NATゲートウェイはマッピングを保持しており、変換を実施してClient Privateへ転送する。 |
7 | 新しいネットワークパスが形成 | クライアントとサーバーは以下のパスで通信を継続する: 1 → 2 → 3 → 4 → 5 → 6 |
IPVSダイレクトルーティングを用いたXDP QUICステアリングの利点
このアプローチは、従来の手法に比べてQUICトラフィックのロードバランシングに対して以下のような利点を提供します:
- クライアントアドレス移行への耐性:
従来のUDPロードバランサーがクライアントのソースアドレスのみに依存するのに対し、本ソリューションはQUIC接続IDを活用します。たとえNAT(ネットワークアドレス変換)によりクライアントのIPアドレスが変更された場合でも、接続IDはターゲットとなる実サーバーのIDを提供します。これにより、実サーバー上のXDP QUICステアリングモジュールは、既存の接続に属するパケットを正確に識別・ルーティングし、再接続を必要とせずにアプリケーションデータの交換を継続できます。
- XDPによる高性能:
XDP層でパケット処理を行うことで、このアプローチはXDPの効率性の恩恵を受けます。XDPは従来のOSプロトコルが介入する前のネットワーク層で動作するため、処理オーバーヘッドが最小限に抑えられ、リアルタイムアプリケーションにとって重要な低レイテンシを実現します。
- IPVSの透明性:
XDP QUICステアリングモジュールは、接続IDに基づいてパケットの内部ルーティングパスを巧妙に変更し、適切な実サーバーへ転送します。なお、モジュールはIPVSに見える宛先アドレスを変更しないため、IPVSのルーティングテーブルやヘルスチェックの整合性が維持され、期待通りのロードバランシングが実現されます。
- 広範なロードバランサーとの互換性:
このアプローチは、DR(ダイレクトルーティング)モードをサポートするほとんどのロードバランサーとシームレスに連携できるように設計されています。DRモードでは、ロードバランサーがあらかじめ定義されたルールに基づいてトラフィックを指定の実サーバーへ直接ルーティングするため、XDP QUICステアリングの接続固有ルーティングと非常に相性が良いです。
- 容易なスケーラビリティ:
本ソリューションは非常にスケーラブルです。各実サーバーにXDP QUICステアリングモジュールを展開することで、プールへのサーバーの追加や削除が容易になり、変動するトラフィック需要に応じたQUICインフラの動的なスケーリングが可能となります。
まとめると、このアプローチは初期トラフィック分散におけるIPVSの強みと、接続ベースのルーティングにおけるXDP QUICステアリングの効率性を組み合わせたものです。これにより、効率的かつ信頼性の高いQUICロードバランシングを実現する魅力的なソリューションとなっています。
なぜこのアプローチはTCPには適用できないのか
IPVSダイレクトルーティングを用いたXDP QUICステアリングは、QUICロードバランシングに対して非常に効果的なソリューションですが、同様のアプローチをTCP接続の維持に適用できるかという疑問が生じます。
答えは いいえ です。その理由は以下の通りです:
- TCPは4タプルに依存:
QUICの接続IDとは異なり、TCP接続は識別およびルーティングのために4タプル(ソースIP、ソースポート、宛先IP、宛先ポート)に依存します。TCPパケットには接続ID要素が存在しないため、XDP QUICステアリングではTCP接続を効果的に追跡および管理することができません。
- TCPの状態管理:
TCP接続は、信頼性のあるデータ配信および順序通りのパケット受信のために、クライアントとサーバーの両端でシーケンス番号やACKウィンドウといった状態情報を確立・維持します。XDP QUICステアリングは低レベルのネットワーク層で動作するため、これらの重要なTCP状態情報を管理または操作する能力がありません。
- TCPの再確立(理想的ではないが):
たとえNATによりTCP接続中にクライアントのソースIPが変更されたとしても、クライアントとサーバーは新しい4タプルを交渉することで接続の再確立を試みることができます。この再確立プロセスは理想的ではありませんが、TCP接続がデータ交換を再開する可能性を提供します。しかし、XDP QUICステアリングはTCP接続の再確立を促進することはできません。
要するに、XDP QUICステアリングは、特にクライアントのアドレスが変更されても管理可能な接続IDという、QUIC固有の特徴を活用するように設計されています。一方、TCP接続は識別、状態管理、および再確立のために異なるメカニズムに依存しているため、このアプローチはTCP接続の維持には適用できません。
重要なポイントは、アドレスマイグレーションがQUICプロトコル固有の機能であるということです。この機能はQUIC接続IDと組み合わさることで、XDP QUICステアリングによる効率的かつ堅牢なロードバランシングを可能にします。一方、TCPプロトコルの制限により、同様の状況下でTCP接続を維持するために本手法を直接適用することはできません。