🚀

Multipath QUICとQUIC-LBについて

2023/05/28に公開

注意事項

本記事は自分の研究用の記録をメインの目的として残しています。
中には仕様が定かではないソースや自分の勉強不足からくる誤解が書いてある可能性があります。あらかじめご了承ください。

以前の記事でMultipath QUICとQUIC-LBのInternet Draftについて読んでみました。
Multipath TCPとL4ロードバランサにおいては、後述するいろんな問題があるようです。
そんな中、表題の組み合わせは実現しうるのか考察してみます。研究の記録として取り扱っていきます。

MultiPath TCP

Multipath TCP(MPTCP)もMPQUICと同じように複数のコネクションを一つのコネクションとしてまとめて接続する技術です。
Multipath TCPはMPQUICとは違い、IPレイヤの情報に基づいて経路を増やします(MPQUICは4-tuppleに基づかないconnection IDで増やします)


画像にあるようにSYNパケットの中にMP_CAPABLEオプションを含め、サーバに3way handshakeの一個目を実施します。
MPTCP対応のサーバは返答するSYN/ACKの両方にMP_CAPABLEオプションを含め返答します。
3つ目の手順でもACKにMP_CAPABLEにこのオプションを含めて送信し、サーバとのハンドシェイクを完了させます。この時点でサーバがMP対応であろうとなかろうとハンドシェイクが完了するため、サーバとの通信を始めることができます。

MP対応だとわかったクライアントはMP_JOINオプションを含んだSYNパケットをサーバに送信し、もう一度3 way handshakeを行います。これが終わることで経路を増やすことができるのです

Multipath TCP and Load Balancer

ロードバランサは複数のサーバを後ろに置いて、負荷を分散するという負荷分散装置です。
L4とL7がありますがここではL4のロードバランサについて記述します。
ネットワークロードバランサ概要

  • 処理する階層:トランスポート層
  • 処理内容:ラウンドロビン、ハッシュ方式
  • 判断材料: ポートとIPアドレス
    ここで、処理内容に幾つかの処理内容が書かれていますが、他にも色々あったりします。

ラウンドロビンで3way handshakeができるわけないというと思いますが、実装では単純にラウンドロビンする訳ではありません。
L4ロードバランサはステートレスタイプとステートフルタイプの二つがあり、後者はコネクションテーブルを持ちます。

ITmediaさんの記事を引用します
https://atmarkit.itmedia.co.jp/ait/articles/0302/05/news001.html

client side client address: 172.16.10.55:1407
client side server address: 10.10.1.100:80
server side client address: 172.16.10.55:1407
server side server address: 192.168.20.1:80
virtual address: 10.10.1.100:80
node address: 192.168.20.1:80
protocol: tcp
sequence number from client: 4119024709
sequence number from server: 1293413027

クライアントからロードバランサに初めのパケットが到着すると、ロードバランサに上のようなコネクションテーブルエントリが作成されます。クライアントからの後続パケットは過去のコネクションテーブルにマッチするか否か判断され、同一コネクションであればエントリ内のサーバに接続します。
 TCPの場合はシーケンス番号まで見て同一コネクションか否か判断されますが、UDPの場合はソースIP/ポート番号が同じであれば一定期間は同一コネクションと判断されます。TCPの場合はFIN(終了処理要求)、ACK、FIN、ACKの4-wayクローズが観察された場合や、RSTパケットによりコネクションテーブルのエントリが消去されます

つまり、5-tupple(送信元IP,送信元ポート番号,宛先IP,宛先ポート番号,プロトコル番号)+シーケンス番号があることでHandshakeを行うことができるということですね

ステートレスロードバランサではこれらの情報を保持するテーブルがありません。代わりに各着信パケットで計算されるハッシュ関数に依存しています。例えば、送信元アドレスと宛先アドレスとポート上でCRCを使用し、各サーバーをさまざまなCRC値に関連付ける方法などがありますね。
ステートレスロードバランサについてはサブフローが同じサーバにたどり着く保証がありません。
このため、色々な対策が提案されてきました。
http://blog.multipath-tcp.org/blog/html/2018/10/04/mptcp_load_balancers.html

QUIC-LB

QUIC-LBもLB自体はステートレスなロードバランサです。
構成エージェントが配下のサーバIDを管理し、サーバに通達します。(ある意味ここはステートフルです)
サーバはコネクションIDを作るとき、サーバIDとロードバランサが構成エージェントを通して確認できる共有鍵からコネクションIDを生成します。
ロードバランサは受け取ったパケットのCIDを見て、鍵を使って復号したCIDにサーバIDを発見することで割り振りを行うことができる訳ですね。
暗号化を行わないplain text方式を下に示します

詳しくは前回記事をご参照ください

Multipath QUIC

MPQUICはNEW_CONNECTION_IDをサーバに受け取った際、CIDを複数作成してもらい、そのコネクションIDを使うことによって通信をすることができます

この時、サーバが生成するConnection IDを先述のQUIC-LBの生成方式によって作成すれば、同じサーバにたどり着くことができる訳です。
こちらも前回記事をご参照ください

他の懸念はないでしょうか?
考えつくところで行くと、

  • NATリバインディング発生の場合
  • PATH_STATUS,PATH_ABANDONフレーム送信の場合。
    あたりがありそうです。
    しかし、いずれの場合でもCIDに変化が起こる訳ではないので、問題なく通信ができそうですね。(あくまで所感)

この辺はスクラップでわかったところがあれば随時追加していきたいところです
https://zenn.dev/eugene/scraps/818dd95411881b

L7LBとMultipath QUICは?

L7ロードバランサとHTTP/3 based on MPQUICを使うときを考えてみます。
前回の記事で紹介した内容ですと、ロードバランサでQUIC通信をオフロードし、ロードバランサとサーバはHTTP/2通信をするみたいです。
では以下のパターンを考えてみます

  • ロードバランサがMPQUIC対応だった場合
    この時は、クライアントとロードバランサの間でコネクションが複数に張られ、一つのコネクションとなります。しかし、ロードバランサとサーバの間ではHTTP/2通信をします。(ここから先は素人考察です)
    ここで、ABのデータをリクエストをする状況を考えてみます。(ロードバランサではAはCID1で、BはCID2でリクエストが届く想定です)
    ここで考慮しなければいけないのが、L7LBはHTTP/2のコネクションをどのようにクライアント-LB間のコネクションと対応づけるかです。
    それぞれのCIDを別々の接続とみなす場合では、AとBを別々のTCPコネクションでサーバにリクエストしなければいけない状況になってしまいます。
    複数のCIDを一つの接続とみなす場合には、上記の状況を防げるものの、ロードバランサにとってはどのCIDがサーバとのTCPコネクションに対応するか判別しなければいけないため厄介になりそうな気がします。
    さらに、ロードバランサのコネクションIDプールのみを逼迫するのでCIDの負荷分散はできていません。これらの状況を鑑みると実装において厄介なことが多そうですね。

  • ロードバランサがMPQUIC非対応だった場合
    この時MPQUICは、ロードバランサと通常のQUICでコネクションを張ります(MPQUICのフェイルオーバ機能)。ですので通常のQUIC通信がされるということですね。サーバがMPQUIC対応してようと関係ありません。

どちらにせよ、Multipath QUICの恩恵は受けれなさそう(or受けれるまで多大な労力がいる)

その他の参考文献

https://hrntknr.net/p/mptcp-lb-2/
https://www.ietf.org/archive/id/draft-duchene-mptcp-load-balancing-01.txt
https://asnokaze.hatenablog.com/entry/20140130/1391095480

Discussion