[アップデート] AWS Gateway Load Balancerにターゲット異常時にRSTパケットを応答する機能が追加され、クライアントが異常を素早く検知できるようになりました
初めに
先週末のアップデートでAWS Gateway Load Balancer(以降GWLB)でターゲットが異常となった場合にGWLBがRSTパケットを返せるオプションが追加されました。
従来のGWLBではフェイルオープン思想でターゲットに異常があった場合でもすでにTCPコネクションが張られている通信については正常なターゲットに振り分けることなく、既にコネクションが貼られている異常なターゲットに対して通信を向け続けるという仕様がありました。
この性質もありクライアントは仮にターゲットに異常があっても応答が返ってこないだけの状態になるため(=異常があるかどうかは通信上判別できない)、そのクライアント指定したタイムアウトを引くまでは異常を検出できず通信が止まるということがありました。
今回のアップデートでは以下のいずれかの条件を満たすとGWLBがRSTパケットをクライアントに返すオプションが追加されました。
- ターゲットがヘルスチェックで異常判定となった場合
- ターゲットグループからの解除
- TCPアイドルタイムアウトの超過
これを有効化することによりクライアントは異常時にRSTパケットを受け取り明示的に終了を受け取るため、クライアント側でRSTを受け取った場合のハンドリングが実装されていれば復旧・異常検知までがこれまでに比べて高速化できるようになります。
設定項目について
設定はGWLB自体ではなくそのターゲットグループ側での指定となります。デフォルトは無効化(従来の設定)なもののマネジメントコンソールの表示としては利用する方が推奨されているようです。
一括で有効化するだけではなくターゲットの異常とターゲットグループ解除時のリセット個別で有効・無効が切り替えられるようです(TCPアイドルタイムアウトの超過はどちらになるんでしょうか)。


検証方法
流石に有料の仮想アプライアンスを使うのは厳しいので何かないかなと探していたところ、aws-gateway-load-balancer-tunnel-handlerというものがあるようでこれをGWLBのターゲットと指定し通信を仲介させてみます。
上記のやつだけで一本記事が書けそうな気がする...というより僕もしっかり理解し切れてはないので詳細は一旦ここでは割愛し別の機会にできればと思います。ここでは一旦そのサービスが通信を仲介してるので止めれば通信も止まる程で理解してもらえたら良いかと思います。
確認については当初tcpdumpで通信を取ろうと思いましたが、今回Session Managerで接続するのとTCPコネクションが切れた時点で通信ができなくなりターミナルの更新が止まるのを利用して確認をします。
具体的にはechoコマンドを1秒ごとにループで流しつつ途中で起動しているサービスを止めます(systemctl stop gwlbtun)。
今回すぐにRSTが送られて再開するのを観測するために2台GWLBのターゲットとして建てていますが、どちらのセッションかはパッとわからないのでその辺はとりあえず片方止めてみて通信が止まったらこっちがそうというガチャをしました。
試してみる
実際に上記の設定の有無効化時にechoを流してみます。
それぞれgifで載せておきますが環境によってはもしかしたら再生されないかもしれませんので怪しそうであれば手元にダウンロードしてもらった方が良いかもしれません。
無効化時
今回の設定を無効化している(従来の場合)は、40秒ぐらいのところでgwlbtunをstopしてるのですがここから通信が返ってきません。

40秒のログの後は止まり続けてて実質的に静止画なのでこれだけだとちょっと様子がわからないと思うのですが、動画時間でいうと10秒くらいのところで止まってからプラス20秒分くらいの動作をgifにしてますがそれ以降は一切タイマーが進んでいない状態で完全にハングしている状態となります(一応ループさせてるのでしばらく流し続けてもらえるとギリわからなくはないと思います)。

有効化時
こちらが有効化した場合となります。こちらは復旧するのでわかりやすいかと思います。

05秒くらいのところから5秒くらい経ってから一気にまとめて流れてますね。
echo自体は裏でネットワークの影響を受けるコマンドではないのでマシン上で走り続けていますが、SSM自体が切れているので画面更新が行われずRSTがかかった後復旧したタイミングでまとめて流れてきてこういった表示になります。
終わりに
新しく追加されたAWS Gateway Load Balancerのターゲット異常時にRSTで通信を終了するオプションを試してみました。
クライアントの実装によりますが明示的にRSTパケットが返ってくることによって多くの場合クライアント側で異常を早い段階で検知し復旧や異常検知ができるのでとりあえず有効化を前提で導入し環境に合わなさそうであれば無効化するという方針で利用してもらってもいいんじゃないかと個人的には思います。
一方でGWLBに関しては集約された通信の出入り口の制御に使われることも多く影響範囲も大きいため、既存環境に関しては十分に検証をした上で有効化してもらえればと思います。
例えば、ヘルスチェックの頻度やタイムアウトが厳しめでピーク時に実はちょくちょくヘルスチェックが一時的に異常になっている(実際には遅延してるだけで通信ができる)のが無理やり切られてしまう、タイムアウトで落ちた場合はリトライするがRSTが返ってくるとリトライせず終了してしまうクライアントがある等思ってもいないところで異常を引く可能性があります。







