VMware NSX Advanced Load Balancer on Azure その6 ~Service Engine 障害時の復旧時間~

これまで、VMware NSX Advanced Load Balancer(以降、NSX ALBと表記)の Azure 上への展開手順について、全5回にわたり紹介してきました。

今回はデータプレーンである Service Engine(以降、SEと表記) 障害検知の仕組みについてご紹介します。

また、過去全5回の記事で構築した検証環境にて、疑似障害を起こして復旧までの時間を確認していきます。

SE 障害検知の仕組み

SE にはクライアントからの接続を受け付ける Virtual Service (以降、VS と表記)が存在します。SE に障害が発生すると、VS へアクセス不可となってサービスへの影響が出てしまいます。

NSX ALB では障害時のサービス影響を最小限に抑えるために、複数の障害検知方法があります。

Controller - SE 間の障害検知

Controller から SE の管理インタフェースに対して、10秒ごとにハートビートを送信します。

6回連続で SE から応答がない場合、障害と判定されます。障害判定後の挙動は SE の高可用性モードによって 異なります。

  • Legacy HA Active/Standby の場合
    • Standby SE が Active となって 障害が起きた SE の VS を引き継ぐ
  • Elastic HA Active-Active の場合
    • 新しい SE が展開されるまでは正常な SE のみで縮退で動作する
  • Elastic HA N+M の場合
    • 正常な SE のバッファに VS が配置される

この検知方法では SE のデータインタフェースの障害検知はできません。

SE - SE 間の障害検知

SE データパスの障害検知は SE 間でハートビートを送信することで実現します。

VS ごとに選出されたプライマリ SE から他の SE (セカンダリ SE)に対して100 msec (カスタマイズ可能)ごとにハートビートを送信します。

10回連続で失敗すると障害の疑いがある旨を Controller に通知します。

Controller は障害疑いのある SE に2秒ごとにエコーメッセージを送信して、4回連続失敗すると障害と判定されます。

合計すると障害検知まで9秒かかります。

上記の障害検知時間についてはメーカのドキュメントに記載されていますが、その後サービス復旧までの時間は高可用性モード設定や連携している Cloud、SE と接続しているネットワーク環境、VS 数により異なりますので、構築後の障害試験は事前に実施頂くことを推奨します。

Azure 連携独自の仕組み

※ 試験結果から推測される執筆者の見解であり、メーカの見解ではありません。

障害検知によってスイッチオーバーが行われて正常な SE が Active になれば通信復旧すると考えていましたが、Azure 連携の場合は SE の前段にある Azure Load Balancer(以降、Azure LB と表記)のバックエンドプールの更新も必要です。

更新は Controller から API で自動で行われます。

また、Azure LB の正常性プローブが5秒間隔で SE に送信されます。正常性プローブの応答が無い場合、Azure LB は 宛先対象から該当 SE を除外します。

SE 障害試験方法

SE 障害検知や Azure 連携独自の仕組みが実際にどのように動作するのか、障害試験を実施してみました。

試験環境は以下の通りです。

試験環境

  • Controller バージョン:22.1.4 Patch なし
  • SE:2台
  • VS:1個(HTTP 80)
  • Pool:2 Web Server
  • SE Group:3種類の高可用性モードにてデフォルト設定を使用しました。

    • Legacy HA Active/Standby

    • Elastic HA Active-Active

    • Elastic HA N+M

  • Alert Config 設定:"VS Switchover"、"VS Add SE"、"SE Heartbeat Failure"の発生時刻を秒単位で表示するため、Alert Config 設定を行いました。

クライアント環境

  • クライアント OS : Windows Server 2022
  • PowerShell: 5.1.20348.2227
  • Curl:8.4.0
  • 試験コマンド:while ($true) {Write-Output "$((Get-Date).AddHours(-9)) $(curl.exe -m 0.5 -s -o NUL -w "%{http_code} %header{date}\n" http://10.3.2.10)" ; start-sleep 0.5}

コマンドの詳細は以下の記事をご参照ください。

Windows で Ping のように HTTP リクエストを定期的に送る方法 - JBS Tech Blog

クライアントはインターネット経由にすると稀にパケットロスが発生するため、Azure 仮想ネットワーク内に配置しました。

試験シナリオ

3種類の高可用性モードで SE 障害時の復旧時間を計測します。

2パターンの障害シナリオで試験を実施します。

試験1:SE 再起動

Azure Portal から SE の再起動を行って復旧時間を計測します。

  • 試験1-1:Legacy HA Active/Standby
  • 試験1-2:Elastic HA Active-Active
  • 試験1-3:Elastic HA N+M
試験2:SE カーネルパニック

疑似障害として SE でカーネルパニックを起こして復旧時間を計測します。

カーネルパニックは Controller 経由で SE に SSHログインして以下のコマンドを実行します。

echo c > /proc/sysrq-trigger

  • 試験2-1:Legacy HA Active/Standby
  • 試験2-2:Elastic HA Active-Active
  • 試験2-3:Elastic HA N+M

試験結果

試験1-1:Legacy HA Active/Standby

  • 復旧時間:23秒

通信不可から11秒後に "SE_Down" と "VS_SWITCHOVER" アラートが発生しました。

SE 間ハートビート失敗による障害検知は9秒とされていますが、アラートが出るまで数秒程度のラグがあるようです。

次に、Azure LB バックエンドプールの更新時刻を確認します。

Azure Monitor の変更分析にて SE のネットワークインタフェース変更履歴を確認したところ、通信不可から20秒~22秒後にバックエンドプールへ追加/削除されていました。

この時刻に新しくアクティブになった SE がバックエンドプールに割当てられたと考えられます。

通信復旧までの流れを図にしました。

試験1-2:Elastic HA Active-Active

  • 復旧時間:8秒(縮退で通信安定するまで)

SE は Active-Active 構成なので、1台に障害発生しても 前段の Azure LB による負荷分散で2回に1回は正常な SE が応答を返していました。

通信不安定状態になってから安定するまで8秒かかりました。

一方で"SE_Down" と "VS_SWITCHOVER" アラームがトリガーされたのは通信不安定から11秒後でした。

SE 障害検知より前に通信安定した理由として、Azure LB の正常性プローブが挙げられます。

正常性プローブに対して応答に失敗した SE を宛先対象から外すことで正常な SE のみ応答できるようになります。

SE 障害検知後は新しい SE が自動で追加されて、およそ3分~8分後に VS が割り当てられ Active-Active 構成に戻りました。

試験1-3:Elastic HA N+M

  • 復旧時間("SE_Down" の理由が "powered down" の時):54秒
  • 復旧時間(Controller - SE 間のハートビート失敗時):130秒(72秒で復旧、その10秒後に通信不安定な状況が50秒近く続いた後に再復旧)

他の高可用性モードと比較して復旧に時間がかかりました。このモードはデフォルト設定で SE は2台展開されますが、1台はバッファ用に確保されて VS は割り当てられない状態となります。

そのため、SE 間のハートビートによる障害検知は行われていないと考えられます。

数十回試験を繰り返した結果、同じ再起動のオペレーションにも関わらずアラート出力が2通りに分かれており、復旧時間も異なる結果となりました。

"SE_Down" の理由が "powered down" の時

通信復旧まで54秒かかりました。

通信不可から42秒後に"SE_Down"アラート出力しました。"SE Heartbeat Failure"アラートは出力されず、Controller は SE が電源オフされたと認識したようです。

同時刻にバッファ SE に VS が追加されたアラートも出ました。

その9秒後にバックエンドプールへ SE 追加/削除されていました。

Controller - SE 間のハートビート失敗時

通信一時復旧まで約72秒かかりました。

通信不可から最大60秒後に Controller - SE 間のハートビート失敗アラートと、バッファ SE への VS 追加アラートが出力されました。

その9秒後に Azure LB バックエンドプールへ SE 追加されて、3秒後に通信復旧しました。

しかし、その10秒後に通信不安定になりました。

アラートを見ると再起動による"SE_Down"が出力されていました。通信復旧後に再起動した訳ではなく、試験のために再起動した SE のアラートが遅れて出力されたようです。

再起動 された SE に対する正常性プローブのメトリックを確認すると、該当時間は100%になっていて正常でした。

バッファ SE として正常状態にあります。バッファなので VS 割当てはされずトラフィック処理は行いません。

しかし、Azure LB のバックエンドプールにてバッファ SE の削除処理がされておらず正常性プローブは成功しているため、トラフィックがバッファ SE に流れてしまってドロップしたため通信不安定になったと考えられます。

バックエンドプールの削除処理は通信不安定になってから約50秒かかっていて、通信復旧時刻とほぼ同じでした。

アクティブな SE が1台のため今回のような動作になりましたが、SE Group 設定で[Scale per Virtual Service]を2にすると最小 SE 数が2台となりますので、Active-Active 2台構成かつバッファ SE が1台ある状態となります。

この状態で アクティブ SE を再起動すると、「試験1-2:HA Active-Active」と同じ復旧時間になります。

更に新規 SE が追加される前にバッファ SE がアクティブになるため、Active-Active構成の復旧も早くなります。

検証では、SE 障害アラートが出力されてからほぼ同時刻に Active-Active 構成は復旧していました。

試験2-1 ~ 2-3

以下の復旧時間になりました。

  • 試験2-1 復旧時間:24秒
    • 試験1-1 とほぼ同じ復旧時間で、復旧までのフローも同様でした。
  • 試験2-2 復旧時間:9秒(縮退で通信安定するまで)
    • 試験1-2 とほぼ同じ復旧時間で、復旧までのフローも同様でした。
  • 試験2-3 復旧時間:132秒(71秒で復旧、その38秒後に通信不安定な状況が23秒近く続いた後に再復旧)
    • 試験1-3 の「Controller - SE 間のハートビート失敗時」とほぼ同じ復旧時間で、復旧までのフローも同様でした。

SE 再起動を手動で実施した場合と、カーネルパニックのような障害が起きた場合で復旧時間に差があると考えてましたが、復旧時間の差はほぼ無かったです。

試験結果まとめ

各試験の復旧時間を表にまとめました。

試験 SE 高可用性モード 試験方法 復旧時間 備考
1-1 Legacy HA Active/Standby SE 再起動 23秒
2-1 Legacy HA Active/Standby カーネルパニック 24秒
1-2 Elastic HA Active-Active SE 再起動 8秒 縮退で通信安定するまでの時間
2-2 Elastic HA Active-Active カーネルパニック 9秒 縮退で通信安定するまでの時間
1-3 Elastic HA N+M SE 再起動 54秒 "SE_Down" の理由が "powered down" の時
1-3 Elastic HA N+M SE 再起動 130秒 Controller - SE 間のハートビート失敗時
2-3 Elastic HA N+M カーネルパニック 132秒

おわりに

想定していた動作と異なる部分もあって、今回の試験を通じて NSX ALB と Azure の細かい連携動作を学習する良い機会となりました。

Elastic HA N+M は アクティブな SE が 1台の場合はネガティブな結果でしたが、2台以上のアクティブな SE で構成すると復旧時間は早くて、バッファもあるので HA 構成に戻る時間も早くメリットがあると感じました。

NSX ALB の連載は本記事をもって一区切りにしたいと思います。ご覧頂きありがとうございました。

執筆担当者プロフィール
菅原 丈晴

菅原 丈晴(日本ビジネスシステムズ株式会社)

ネットワーク機器の設計/構築エンジニア。最近は仮想基盤・クラウドを触っています。

担当記事一覧