Amazon Web Services ブログ
ゾーン自動シフト — 潜在的な問題を検出すると、トラフィックをアベイラビリティーゾーンから自動的に移動させます
11月30日、Amazon Route 53 Application Recovery Controller の新機能であるゾーン自動シフトを公開しました。これにより、AWS がそのアベイラビリティーゾーンに影響する潜在的な障害を特定したときに、ワークロードのトラフィックをアベイラビリティーゾーンから自動的にかつ安全に移動し、障害が解決したら元のアベイラビリティーゾーンに復元できます。
耐障害性の高いアプリケーションのデプロイでは、通常、リソースをリージョンの複数のアベイラビリティーゾーンにデプロイします。アベイラビリティーゾーンとは、さまざまな電力、接続、ネットワークデバイス、および氾濫原管理を確保するために、通常数マイル離れた物理データセンターの個別のグループのことです。
デプロイの失敗、構成の誤り、オペレーターのミスなど、アプリケーションのエラーからユーザーを保護するために、当社では昨年、手動またはプログラムでゾーンシフトをトリガーする機能を導入しました。 これにより、あるアベイラビリティーゾーンでメトリクス値の低下が検出したときに、トラフィックをそのアベイラビリティーゾーンから遠ざけることができます。そのためには、すべての新しい接続を正常なアベイラビリティーゾーンのインフラストラクチャのみに転送するようにロードバランサーを設定します。これにより、障害の根本原因を調査する間、顧客はアプリケーションの利用を継続できます。障害が解消されたら、ゾーンシフトを停止して、トラフィックが再びすべてのゾーンに分散されるようにします。
ゾーンシフトは、NLB のデフォルトであるクロスゾーン負荷分散が無効になっている場合にのみ、Application Load Balancer (ALB) または Network Load Balancer (NLB) レベルで機能します。簡単に言うと、ロードバランサーには 2 つのレベルの負荷分散があります。最初のレベルは DNS で設定されます。ロードバランサーはアベイラビリティーゾーンごとに 1 つ以上の IP アドレスを公開し、ゾーン間のクライアント側の負荷分散を実現します。トラフィックがアベイラビリティーゾーンに到達すると、ロードバランサーは登録された正常なターゲット (通常は Amazon Elastic Compute Cloud (Amazon EC2) インスタンス) にトラフィックを送信します。デフォルトでは、ALB はすべてのアベイラビリティーゾーンのターゲットにトラフィックを送信します。ゾーンシフトを正しく機能させるには、クロスゾーン負荷分散を無効にするようにロードバランサーを設定する必要があります。
ゾーンシフトが始まると、次の図に示すように、DNS はすべてのトラフィックをあるアベイラビリティーゾーンから遠ざけます。
手動によるゾーンシフトは、ユーザー側で発生したエラーからワークロードを保護するのに役立ちます。しかし、アベイラビリティーゾーンで障害が発生した可能性がある場合、障害の特定や検出が困難な場合があります。ほとんどの場合、アベイラビリティーゾーンごとにメトリクスを追跡することはないため、アプリケーションメトリックスを使用してアベイラビリティーゾーンの問題を検出することは困難です。さらに、サービスがアベイラビリティーゾーンの境界を越えて依存関係を呼び出すことが多く、その結果、すべてのアベイラビリティーゾーンでエラーが発生してしまいます。最新のマイクロサービスアーキテクチャでは、これらの検出と復旧の手順を数十または数百の個別のマイクロサービスで実行しなければならないことが多く、復旧に数時間かかってしまいます。
お客様から、アベイラビリティーゾーンで発生した可能性のある障害を特定する負担を軽減できないかと問い合わせがありました。結局のところ、当社が内部のモニタリングツールを使用すれば、潜在的な問題についてお客様より先に検出できる可能性があります。
今回のリリースにより、アベイラビリティーゾーンで発生する可能性のある障害からワークロードを保護するゾーン自動シフトを設定できるようになりました。当社では、ネットワークトラフィックのシフトをいつトリガーするかを決定するために、独自の AWS 内部モニタリングツールとメトリクスを利用します。シフトは自動的に開始され、API を呼び出す必要はありません。ゾーンに電源障害やネットワーク障害などの潜在的な障害が発生していることが検出されると、インフラストラクチャの NLB または ALB トラフィックの自動シフトが自動的にトリガーされ、障害が解決された時点でトラフィックを元に戻します。
言うまでもなく、トラフィックをアベイラビリティーゾーンから遠ざけることはデリケートなオペレーションであり、慎重に準備する必要があります。アプリケーションの可用性を誤って低下させないように、一連の保護手段を構築しました。
まず、トラフィックを一度に複数のアベイラビリティーゾーンから移動させないようにするための内部制御が必要です。次に、毎週 30 分間、インフラストラクチャの移行を演習します。例えば、月曜日から金曜日の 08:00~18:00 など、演習をブロックする時間帯を定義できます。3 つ目は、演習実行中のサーキットブレーカーとして機能する 2 つの Amazon CloudWatch アラームを定義することです。一方は演習の実行をまったく開始しないようにするアラーム、他方は演習実行中のアプリケーションの状態をモニタリングするアラームです。演習中にどちらかのアラームがトリガーされると、停止し、すべてのアベイラビリティーゾーンへのトラフィックを復元します。演習実行終了時のアプリケーションヘルスアラームの状態は、実行の結果 (成功または失敗) を示します。
責任共有の原則によれば、2 つの責任があります。
まず、すべてのアベイラビリティーゾーンに十分な容量がデプロイされていることを確認して、トラフィックが移動した後に残りのアベイラビリティーゾーンのトラフィックが増加しても対応できるようにする必要があります。残りのアベイラビリティーゾーンには常に十分な容量を確保し、アプリケーションの復旧を遅らせたり可用性に影響を与えたりする可能性のあるスケーリングメカニズムに依存しないことを強くお勧めします。ゾーン自動シフトがトリガーされると、AWS Auto Scaling はリソースをスケーリングするのに通常よりも時間がかかる場合があります。リソースを事前にスケーリングすることで、最も要求の厳しいアプリケーションの復旧時間を予測できます。
通常のユーザートラフィックを吸収するために、アプリケーションが 3 つのアベイラビリティーゾーンに 6 つの EC2 インスタンス (2×3 インスタンス) を必要とするとします。ゾーン自動シフトを設定する前に、1 つのアベイラビリティーゾーンが利用できない場合にトラフィックを吸収するのに十分な容量が残りのアベイラビリティーゾーンにあることを確認する必要があります。この例では、1 つのアベイラビリティーゾーンにつき 3 つのインスタンス (トラフィックが 2 つのアベイラビリティーゾーンに移動されたときに 2×3 = 6 つのインスタンスを維持して負荷分散する必要があるため、3 つのアベイラビリティーゾーンに 3×3 = 9 つのインスタンスが必要) という意味です。
実際には、高い信頼性が求められるサービスを運用する場合、顧客による負荷の急上昇や時折のホスト障害などの不測の事態に備えて、ある程度の冗長容量をオンラインで運用するのが一般的です。この方法で既存の冗長性を満たすことで、アベイラビリティーゾーンの問題が発生したときに迅速に復旧できるだけでなく、他のイベントに対する堅牢性も高まります。
次に、選択したリソースのゾーン自動シフトを明示的に有効にする必要があります。AWS は、選択したリソースにのみゾーン自動シフトを適用します。ゾーン自動シフトを適用すると、アプリケーションに割り当てられる合計容量に影響します。先ほど説明したように、残りのアベイラビリティーゾーンに十分な容量をデプロイして、アプリケーションを準備する必要があります。
もちろん、この追加容量をすべてのアベイラビリティーゾーンにデプロイすることにはコストがかかります。耐障害性について話すとき、アプリケーションの可用性とコストのどちらを決めるかというビジネス上のトレードオフがあることを説明します。これが、選択したリソースにのみゾーン自動シフトを適用するもう 1 つの理由です。
ゾーン自動シフトの設定方法を見てみましょう
ゾーン自動シフトの設定方法を示すために、今や有名になった TicTacToe ウェブアプリケーションを CDK スクリプトを使ってデプロイします。AWS マネジメントコンソールの [Route 53 Application Recovery Controller] ページを開きます。左側のペインで、[ゾーン自動シフト] を選択します。次に、ウェルカムページで、[リソースのゾーン自動シフトを設定] を選択します。
デモアプリケーションのロードバランサーを選択します。現在のところクロスゾーン負荷分散が無効になっているロードバランサーのみがゾーン自動シフトの対象であるということに注意してください。コンソールの警告からもわかるように、アベイラビリティーゾーンが 1 つ失われても動作を継続するのに十分な容量がアプリケーションにあることも確認しています。
ページを下にスクロールして、AWS に 30 分間の演習を実行させたくない時間と曜日を設定します。最初は、自動シフトに慣れるまで、月曜日から金曜日の 08:00〜18:00 は演習をブロックします。時刻は UTC で表示され、夏時間は適用されないことに注意してください。UTC 時間変換アプリケーションを使用すると便利です。最初は営業時間を外して問題ありませんが、アプリケーションのトラフィックが少ないときやまったくない場合には表示されない可能性がある問題を確実にキャプチャできるように、営業時間中にも演習を実行するように設定することをお勧めします。ピーク時に衝撃を与えずに機能させるには、おそらくゾーン自動シフトが最も必要ですが、テストしたことがない場合は、どの程度自信がありますか? 常時ブロックしないのが理想ですが、それが常に現実的であるとは限らないことを私たちは認識しています。
同じページのさらに下にある 2 つのサーキットブレーカーアラームを入力します。最初のものは演習の開始を妨げます。このアラームを使って、今は演習を始めるのに良いタイミングではないと示します。例えば、アプリケーションで現在問題が発生している場合や、アプリケーションの新しいバージョンを本番環境にデプロイする場合などです。2 番目の CloudWatch アラームは、演習実行の結果を示します。これにより、ゾーン自動シフトにより、アプリケーションが演習実行にどのように反応しているかを判断できます。アラームが緑色のままであれば、すべてがうまくいったことがわかります。
演習中にこれら 2 つのアラームのいずれかがトリガーされると、ゾーン自動シフトは演習を停止し、すべてのアベイラビリティーゾーンへのトラフィックを復元します。
最後に、30 分間の演習実行が毎週実行され、アプリケーションの可用性が低下する場合があることを認めます。
その後、[Create] を選択します。
数日後、コンソールの [リソースのゾーンシフト履歴] タブに演習実行の履歴が表示されます。2 つのサーキットブレーカーアラームの履歴をモニタリングして、すべてが正しくモニタリングされ、設定されていることを確認しています。
自動シフト自体をテストすることはできません。アベイラビリティーゾーンで潜在的な問題を検出すると、自動的にトリガーされます。この記事で共有した手順をテストするためにアベイラビリティーゾーンをシャットダウンできるかどうかサービスチームに尋ねたところ、丁寧に断られました。
自動シフトと同じように動作する手動シフトをトリガーすれば、設定のテストができます。
さらに押さえておくべきこと
ゾーン自動シフトは、中国と GovCloud を除くすべての AWS リージョンで追加料金なしで利用できるようになりました。
クロール、ウォーク、ラン方式の適用をお勧めします。まず、手動のゾーンシフトから始め、アプリケーションに対する信頼性を確立します。次に、営業時間外に演習実行を設定したゾーン自動シフトを有効にします。最後に、営業時間中のゾーンシフトの演習を含めるようにスケジュールを変更します。イベントが発生したくないときに、イベントに対するアプリケーションの応答をテストしたいと考えています。
また、トラフィックを 1 つのアベイラビリティーゾーンから別のアベイラビリティーゾーンに戻したときに、アプリケーションのすべての部分がどのように復旧するかを総合的に考えることをお勧めします。私が思いつくリスト (完全なものではありませんが) は次のようなものです。
まず、すでに説明したように、容量増加の計画を立てます。次に、各アベイラビリティーゾーンで発生する可能性のある単一障害点について考えてみましょう。例えば、単一の EC2 インスタンスで実行される自己管理型データベースや、1 つのアベイラビリティーゾーンに存在するマイクロサービスなどです。ゾーンシフトを必要とするアプリケーションには、Amazon DynamoDB や Amazon Aurora などのマネージドデータベースを使用することを強くお勧めします。これらには、レプリケーションとフェイルオーバーのメカニズムが組み込まれています。3 番目に、アベイラビリティーゾーンが再び利用可能になったときに切り替える計画を立ててください。リソースのスケーリングにはどの程度の時間が必要ですか? キャッシュをリハイドレートする必要がありますか?
耐障害性の高いアーキテクチャと方法論について詳しくは、同僚の Adrian が執筆したこの素晴らしい記事シリーズをご覧ください。
最後に、現在ゾーン自動シフトの対象となるのは、クロスゾーン負荷分散が無効になっているロードバランサーのみであることに注意してください。CDK スクリプトからクロスゾーン負荷分散を無効にするには、stickinessCookieDuration
を削除し、ターゲットグループに load_balancing.cross_zone.enabled=false
を追加する必要があります。CDK とタイプスクリプトを使った例を以下に示します。
// 負荷分散として Auto Scaling グループを追加します
// リスナーをターゲットにします。
const targetGroup = listener.addTargets('MyApplicationFleet', {
port: 8080,
// ゾーンシフトでは、維持設定とクロスゾーンの負荷分散を無効にする必要があります
// stickinessCookieDuration: Duration.hours(1),
targets: [asg]
});
// クロスゾーン負荷分散を無効にする
targetGroup.setAttribute("load_balancing.cross_zone.enabled", "false");
次は、ゾーン自動シフトのメリットが得られるアプリケーションを選択します。まず、各アベイラビリティーゾーンのインフラストラクチャ容量を確認してから、サーキットブレーカーアラームを定義します。モニタリングが正しく設定されていることを確認したら、ゾーン自動シフトを有効にしてください。
原文はこちらです。