Amazon EKS での Amazon Application Recovery Controller (ARC) のゾーンシフトの詳細
Kubernetes には、アベイラビリティーゾーン (AZ) のヘルスの低下や障害などのイベントに対するアプリケーションの回復力を高めるネイティブ機能があります。Amazon EKS クラスターでワークロードを実行する場合、Amazon Application Recovery Controller (ARC) のゾーンシフトまたはゾーンオートシフトを使用して、アプリケーション環境の耐障害性とアプリケーション復旧をさらに改善できます。ARC ゾーンシフトは、ゾーンシフトが期限切れになるまで、またはキャンセルするまで、障害のある AZ からリソースのトラフィックを移動できる一時的な手段として設計されています。必要に応じてゾーンシフトを拡張できます。
EKS クラスターのゾーンシフトを開始することも、ゾーンオートシフトを有効にして AWS がゾーンシフトを実行できるようにすることもできます。このシフトは、正常な AZ のワーカーノードで実行されているポッドのネットワークエンドポイントのみを使用するようにクラスター内の東西ネットワークトラフィックのフローを更新します。さらに、EKS クラスター内のアプリケーションの入力トラフィックを処理する ALB または NLB は、トラフィックを正常な AZ 内のターゲットに自動的にルーティングします。可用性を最大限に高めることを目標にしているお客様にとって、AZ で障害が発生した場合は、障害のある AZ が回復するまでその AZ からすべてのトラフィックを移動できることが重要です。そのためには、ARC ゾーンシフト で ALB または NLB を有効にすることもできます。
ポッド間の東西ネットワークトラフィックフローを理解する
次の図は、2 つのワークロードの例である Orders と Products を示しています。この例の目的は、さまざまな AZ でワークロードとポッドが通信する方法を示します。
-
Orders が Products と通信するには、まず送信先のサービスの DNS 名を解決する必要があります。Orders は CoreDNS と通信して、そのサービスの仮想 IP アドレス (クラスター IP) を取得します。Orders が Products のサービス名を解決すると、そのターゲット IP にトラフィックが送信されます。
-
kube-proxy はクラスター内のすべてのノードで実行され、EndpointSlices
for Services を継続的に監視します。サービスが作成されると、EndpointSlice コントローラーによってバックグラウンドで EndpointSlice が作成され、管理されます。各 EndpointSlice には、ポッドアドレスのサブセットと、それらが実行されているノードを含むエンドポイントのリストまたは表があります。kube-proxy は、ノードで iptables
を使用して、これらのポッドエンドポイントごとにルーティングルールを設定します。また、kube-proxy は、基本的なロードバランシングも行います。サービスのクラスター IP 宛てのトラフィックを、ポッドの IP アドレスに直接送信するようリダイレクトします。kube-proxy は、送信接続の送信先 IP を書き換えることでこれを行います。 -
次に、ネットワークパケットは、各ノードの ENI を介して AZ 2 の Products ポッドに送信されます (上の図を参照)。
EKS での ARC ゾーンシフトについて
環境に AZ の障害がある場合は、EKS クラスター環境のゾーンシフトを開始できます。または、ゾーンオートシフトを使用して AWS がこれを管理できます。ゾーンオートシフトでは、AWS は AZ の全体的なヘルスをモニタリングし、クラスター環境内の障害のある AZ からトラフィックを自動的に移動することで、潜在的な AZ 障害に対応します。
ARC で EKS クラスターゾーンシフトを有効にすると、ARC コンソール、AWS CLI、またはゾーンシフト API やゾーンオートシフト API を使用して、ゾーンシフトをトリガーしたり、ゾーンオートシフトを有効にしたりできます。EKS ゾーンシフト中、次のことが自動的に行われます。
-
影響を受ける AZ 内のすべてのノードが遮断されます。これにより、Kubernetes スケジューラーが異常な AZ のノードに新しいポッドをスケジューリングできなくなります。
-
マネージドノードグループを使用している場合、アベイラビリティーゾーンの再分散は停止され、Auto Scalingグループ (ASG) が更新され、新しい EKS データプレーンノードが正常な AZ でのみ起動されるようにします。
-
異常な AZ のノードは終了されず、ポッドはこれらのノードから削除されます。これは、ゾーンシフトの有効期限が切れたりキャンセルされたりしたときに、トラフィックがフル容量を保持している AZ に安全に戻ることができるようにするためです。
-
EndpointSlice コントローラーは、障害のある AZ 内のすべてのポッドエンドポイントを検索し、関連する EndpointSlices から削除します。これにより、正常な AZ のポッドエンドポイントのみがネットワークトラフィックの受信対象になります。ゾーンシフトがキャンセルまたは期限切れになると、EndpointSlice コントローラーは EndpointSlices を更新して、復元された AZ にエンドポイントを含めます。
以下の図は、EKS ゾーンシフトによって、クラスター環境で正常なポッドエンドポイントのみがターゲットにされる方法についての大まかなフローを示しています。
EKS ゾーンシフトの要件
ゾーンシフトを EKS で正常に機能させるには、事前に AZ の障害に対する回復性を実現できるようにクラスター環境を設定する必要があります。以下は、従う必要があるステップのリストです。
-
複数の AZ にクラスターのワーカーノードをプロビジョニングする
-
1 つの AZ の削除に耐えるのに十分なコンピューティング容量をプロビジョニングする
-
すべての AZ でポッド (CoreDNS を含む) をプリスケールする
-
すべての AZ に複数のポッドレプリカを分散して、単一の AZ から移動することで十分な容量を確保できるようにします。
-
相互依存ポッドまたは関連ポッドを同じ AZ に配置する
-
ゾーンシフトを手動で開始することで、少ない AZ でクラスター環境が期待どおりに動作することをテストします。または、ゾーンオートシフトを有効にし、オートシフトの練習運用に頼ることもできます。これは、ゾーンシフトが EKS で機能するためには必要ありませんが、強くお勧めします。
複数の AZ に EKS ワーカーノードをプロビジョニングする
AWS リージョンには、アベイラビリティーゾーン (AZ) と呼ばれる物理データセンターがある複数の別々の場所があります。AZ は、リージョン全体に影響を与える可能性のある同時障害を回避するために、互いに物理的に離れた場所に配置されています。EKS クラスターをプロビジョニングする場合は、リージョン内の複数の AZ にワーカーノードをデプロイする必要があります。これにより、クラスター環境は 1 つの AZ の障害に対する回復力が向上し、他の AZ で実行されているアプリケーションの高可用性 (HA) を維持できます。影響を受ける AZ からゾーンシフトを開始すると、EKS 環境のクラスター内ネットワークは自動的に更新されて正常な AZ のみが使用されますが、クラスターの高可用性は維持されます。
EKS 環境にこのようなマルチ AZ 設定を実施することで、システム全体の信頼性が向上します。ただし、マルチ AZ 環境は、アプリケーションデータの転送と処理方法に大きな役割を果たし、環境のネットワーク料金に影響します。特に、頻繁な egress クロスゾーントラフィック (AZ 間に分散されたトラフィック) は、ネットワーク関連のコストに大きな影響を与える可能性があります。さまざまな戦略を適用して、EKS クラスター内のポッド間のクロスゾーントラフィックの量を制御し、関連するコストを削減できます。高可用性 EKS 環境を実行するときにネットワークコストを最適化する方法の詳細については、このベストプラクティスガイド
以下の図は、3 つの正常な AZ を持つ高可用性 EKS 環境を示しています。
次の図は、3 つの AZ を持つ EKS 環境が AZ の障害に対して回復力があり、他の 2 つの正常な AZのために高可用性を維持する方法を示しています。
1 つの AZ の削除に耐えるのに十分なコンピューティング容量をプロビジョニングする
EKSデータプレーンでコンピューティングインフラストラクチャのリソース使用率とコストを最適化するには、コンピューティング容量をワークロード要件に合わせることをお勧めします。ただし、すべてのワーカーノードがフル容量である場合、新しいポッドをスケジュールする前に、新しいワーカーノードを EKS データプレーンに追加する必要があります。重要なワークロードを実行する場合、通常、負荷の急増やノードのヘルスの問題などに対処するために、冗長な容量をオンラインで運用することをお勧めします。ゾーンシフトを使用する予定がある場合、AZ 全体の容量を取り除くことを計画していることになります。そのため、AZ がオフラインになった状態でも負荷を処理できるように、冗長なコンピューティング容量を調整する必要があります。
コンピューティングをスケーリングする場合、EKS データプレーンに新しいノードを追加するプロセスには時間がかかるため、特にゾーンの障害が発生した場合に、アプリケーションのリアルタイムのパフォーマンスと可用性に影響を与える可能性があります。EKS 環境は、エンドユーザーやクライアントのエクスペリエンスの低下を避けるために、AZ を失った場合の負荷を吸収する回復力がある必要があります。これは、新しいポッドが必要な時点からワーカーノードで実際にスケジュールされる時点までの遅延を最小限に抑えるか、排除することを意味します。
さらに、ゾーンの障害が発生した場合は、潜在的なコンピューティング容量の制約のリスクを軽減する必要があります。これにより、新しく必要なノードが正常な AZ の EKS データプレーンに追加されるのを防ぐことができます。
これを実現するには、特に環境内の AZ が 1 つ少ない場合に Kubernetes スケジューラーが新しいポッドの配置に使用できる既存の容量を持つように、各 AZ の一部のワーカーノードでコンピューティング容量をオーバープロビジョニングする必要があります。
複数のポッドレプリカを AZ 間で実行して分散する
Kubernetes を使用すると、1 つのアプリケーションの複数のインスタンス (ポッドレプリカ) を実行してワークロードを事前スケールできます。アプリケーションに対して複数のポッドレプリカを実行すると、単一障害点がなくなり、1 つのレプリカへのリソースの負担が軽減されることで、全体的なパフォーマンスが向上します。ただし、アプリケーションの高可用性と耐障害性向上を実現するには、異なる障害ドメイン (トポロジドメイン、ここでは AZ) にまたがってアプリケーションの複数のレプリカを分散させて実行する必要があります。トポロジ分散制約
下図は、すべての AZ が正常である場合の、EKS 環境と東西トラフィックフローを示しています。
下図は、1 つの AZ で障害が発生し、ゾーンシフトを開始したときの、東から西へのトラフィックフローを持つ EKS 環境を示しています。
以下のコードスニペットは、この Kubernetes 機能を使用してワークロードを設定する方法の例です。
apiVersion: apps/v1 kind: Deployment metadata: name: orders spec: replicas: 9 selector: matchLabels: app:orders template: metadata: labels: app: orders tier: backend spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: app: orders
最も重要なのは、DNS サーバーソフトウェア (CoreDNS/kube-dns) の複数のレプリカを実行し、それらがデフォルトでまだ設定されていない場合は、同様のトポロジ分散制約を適用することです。これにより、正常な AZ に十分な DNS ポッドがあり、単一の AZ 障害がある場合にクラスター内の他の通信ポッドのサービス検出リクエストを引き続き処理できます。CoreDNS EKS アドオンには、複数の AZ に使用可能なノードがある場合に、クラスターのアベイラビリティーゾーンに CoreDNS ポッドを分散するためのデフォルト設定があります。これらのデフォルト設定を独自のカスタム設定に置き換えることもできます。
Helm で CoreDNSreplicaCount
を更新して、各 AZ に十分な数のレプリカを確保できます。さらに、これらのレプリカがクラスター環境内の異なる AZ に分散されるようにするには、同じ values.yaml ファイルで topologySpreadConstraints
プロパティを更新する必要があります。以下のコードスニペットは、これに対して CoreDNS を設定する方法を示しています。
CoreDNS Helm の values.yaml
replicaCount: 6 topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: k8s-app: kube-dns
AZ の障害が発生した場合は、CoreDNS の自動スケーリングシステムを使用して CoreDNS ポッドの負荷の増加を吸収できます。必要な DNS インスタンスの数は、クラスターで実行されているワークロードの数によって異なります。CoreDNS は CPU バインドであり、Horizontal Pod Autoscaler (HPA)
apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: coredns namespace: default spec: maxReplicas: 20 minReplicas: 2 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: coredns targetCPUUtilizationPercentage: 50
また、EKS は、CoreDNS の EKS アドオンバージョンで CoreDNS デプロイの自動スケーリングを管理できます。この CoreDNS オートスケーラーは、ノード数や CPU コア数など、クラスターの状態を継続的にモニタリングします。この情報に基づいて、コントローラーは EKS クラスター内の CoreDNS デプロイのレプリカ数を動的に調整します。
CoreDNS EKS アドオン で自動スケーリング設定を有効にするには、次のオプションの設定を追加する必要があります。
{ "autoScaling": { "enabled": true } }
NodeLocal DNS
同じ AZ で相互依存ポッドを同じ場所に配置する
ほとんどの場合、エンドツーエンドプロセスの実行を成功させるために相互に通信する必要がある個別のワークロードを実行している可能性があります。異なるアプリケーションが異なる AZ に分散しているが、同じ AZ に配置されていない場合、単一の AZ の障害が基盤となるエンドツーエンドのプロセスに影響を与える可能性があります。例えば、アプリケーション A には AZ 1 と AZ 2 に複数のレプリカがあるが、アプリケーション B には AZ 3 にすべてのレプリカがある場合、AZ 3 が失われると、これら 2 つのワークロード (アプリケーション A と B) 間のエンドツーエンドプロセスに影響します。トポロジ分散制約とポッドのアフィニティを組み合わせると、すべての AZ にポッドを分散させ、特定のポッド間の関係を設定して、それらが一緒に配置されるようにすることで、アプリケーションの回復性を強化できます。
ポッドのアフィニティのルール
apiVersion: apps/v1 kind: Deployment metadata: name: products namespace: ecommerce labels: app.kubernetes.io/version: "0.1.6" spec: serviceAccountName: graphql-service-account affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - orders topologyKey: "kubernetes.io/hostname"
下図は、ポッドアフィニティルールを使用して同じノードに共に配置されたポッドを示しています。
クラスター環境が AZ の損失を処理できることをテストする
上記の要件を完了したら、次の重要なステップは、AZ の損失を処理するのに十分なコンピューティングとワークロード容量があることをテストすることです。これを行うには、EKS でゾーンシフトを手動でトリガーします。または、ゾーンオートシフトを有効にして練習実行を設定して、クラスター環境内の AZ を 1 つ減らしてアプリケーションが期待どおりに機能することをテストすることもできます。
よくある質問
この機能を使用する理由は何ですか?
EKS クラスターで ARC ゾーンシフトまたはゾーンオートシフトを使用することで、クラスター内ネットワークトラフィックを障害のある AZ から移行する迅速な復旧プロセスを自動化することで、Kubernetes アプリケーションの可用性をより適切に維持できます。ARC を使用すると、障害のある AZ イベント中に回復期間を延長することの多い、長く複雑なステップを回避できます。
この機能は他の AWS サービスとどのように連携しますか?
EKS は ARC と統合され、AWS で復旧オペレーションを実行するためのプライマリインターフェイスを提供します。クラスター内トラフィックが障害のある AZ から適切にルーティングされるように、Kubernetes データプレーンで実行されているポッドのネットワークエンドポイントのリストが変更されます。クラスターへの外部トラフィックのルーティングに AWS Load Balancer を使用している場合は、ロードバランサーを ARC に登録し、ゾーンシフトをトリガーして、トラフィックが機能低下したゾーンに流れるのを防ぐことができます。この機能は、EKS マネージド型ノードグループ (MNG) によって作成された Amazon EC2 Auto Scaling グループ (ASG) とも相互作用します。障害のある AZ が新しい Kubernetes ポッドまたはノードの起動に使用されるのを防ぐため、EKS は障害のある AZ を ASG から削除します。
この機能はデフォルトの Kubernetes 保護とどのように異なりますか?
この機能は、顧客が回復力を維持するのに役立ついくつかの Kubernetes ネイティブ組み込み保護と連携して機能します。ポッドの準備状況とライブネスプローブを設定して、ポッドがいつトラフィックを取るかを決定できます。これらのプローブで障害が発生すると、Kubernetes はこれらのポッドをサービスのターゲットとして削除し、トラフィックはポッドに送信されなくなります。これは便利ですが、ゾーンが機能低下したときに障害が発生することが保証されるように、これらのヘルスチェックを設定するのは簡単ではありません。ARC ゾーンシフト機能には、Kubernetes のネイティブ保護が十分でない場合に、機能低下した AZ を完全に分離するのに役立つ追加のセーフティネットが用意されています。また、アーキテクチャの運用準備状況と回復性を簡単にテストする方法も用意されています。
AWS はユーザーに代わってゾーンシフトをトリガーできますか?
はい。ARC ゾーンシフトを完全に自動化する方法が必要な場合は、ARC ゾーンオートシフトを有効にできます。ゾーンオートシフトでは、 AWS を使用して EKS クラスターの AZ の状態を監視し、AZ の障害が検出されるとシフトを自動的にトリガーできます。
この機能を使用し、ワーカーノードとワークロードが事前にスケーリングされていない場合はどうなりますか?
ゾーンシフト中に事前スケールされておらず、追加のノードやポッドのプロビジョニングに依存している場合、復旧が遅れるリスクがあります。Kubernetes データプレーンに新しいノードを追加するプロセスには時間がかかるため、特にゾーンの障害が発生した場合に、アプリケーションのリアルタイムのパフォーマンスと可用性に影響を与える可能性があります。さらに、ゾーンの障害が発生した場合は、コンピューティング容量の制約により、新たに必要なノードが正常な AZ に追加できなくなる可能性があります。
ワークロードが事前にスケールされておらず、クラスター内のすべての AZ に分散されていない場合、ゾーンの障害により、影響を受ける AZ のワーカーノードでのみ実行されているアプリケーションの可用性に影響する可能性があります。アプリケーションの可用性が完全に停止するリスクを軽減するため、EKS にはフェイルセーフ機能があります。この機能により、ワークロードのすべてのエンドポイントが障害が発生している AZ にある場合でも、障害ゾーンのポッドエンドポイントにトラフィックを送信することが可能です。ただし、ゾーンの問題が発生した場合でも可用性を維持するために、アプリケーションを事前にスケールしてすべての AZ に分散することを強くお勧めします。
ステートフルアプリケーションを実行している場合はどうなりますか?
ステートフルアプリケーションを実行している場合は、ユースケースとアーキテクチャに応じて耐障害性を評価する必要があります。アクティブ/スタンバイのアーキテクチャまたはパターンがある場合、アクティブが障害のある AZ にある可能性があります。アプリケーションレベルでは、スタンバイがアクティブ化されていない場合、アプリケーションに問題が発生する可能性があります。また、正常な AZ で新しい Kubernetes ポッドを起動すると、障害のある AZ にバインドされた永続的なボリュームにアタッチできないため、問題が発生する可能性があります。
この機能は Karpenter で機能しますか?
Karpenter のサポートは現在、ARC ゾーンシフトと EKS のゾーンオートシフトでは利用できません。AZ に障害がある場合は、異常な AZ を削除して、関連する Karpenter NodePool 設定を調整し、新しいワーカーノードが正常な AZ でのみ起動されるようにすることができます。
この機能は EKS Fargate で機能しますか?
この機能は EKS Fargate では機能しません。デフォルトでは、EKS Fargate がゾーンヘルスイベントを認識すると、ポッドは他の AZ での動作を優先します。
EKS マネージド Kubernetes コントロールプレーンは影響を受けますか?
いいえ。デフォルトでは、Amazon EKS は、複数の AZ で Kubernetes コントロールプレーンを実行およびスケールして、高可用性を実現します。ARC ゾーンシフトとゾーンオートシフトは、Kubernetes データプレーンでのみ動作します。
この新機能に関連するコストはありますか?
EKS クラスターでは、ARC ゾーンシフトとゾーンオートシフトを追加料金なしで使用できます。ただし、プロビジョニングされたインスタンスの料金は引き続きお支払いいただきます。この機能を使用する前に、Kubernetes データプレーンを事前にスケールすることを強くお勧めします。コストとアプリケーションの可用性の適切なバランスを考慮する必要があります。