高可用性 (HA) とは、サービスの信頼性と継続性を確保するためのシステム設計です。Container Service for Kubernetes (ACK) は、Kubernetes アーキテクチャに基づいたさまざまなクラスター HA メカニズムを提供し、コントロールプレーン、ノード、ノードプール、ワークロード、およびロードバランサーの高可用性を確保します。これにより、安定した安全で信頼性の高いクラスターとアプリケーションアーキテクチャを構築できます。
このトピックについて
このトピックは、ACK クラスターの開発者と管理者を対象としています。このトピックの提案は、HA クラスターの計画と作成に役立ちます。Container Service for Kubernetes 実際の構成は、クラスターの環境とビジネスによって異なる場合があります。このトピックでは、コントロールプレーンとデータプレーンの推奨 HA 構成を参照できます。
構成 | 保守担当 | 該当するクラスタータイプ |
ACK によって管理されています。 | 以下の ACK クラスターにのみ適用されます:ACK マネージドクラスター (Basic 版と Pro 版)、Serverless Kubernetes クラスター (Basic 版と Pro 版)、ACK Edge クラスター、および ACK Lingjun クラスター。専用クラスターや登録済みクラスターなど、他のクラスターのコントロールプレーンは、お客様自身で保守する必要があります。したがって、コントロールプレーンアーキテクチャ HA はこれらのクラスターには適用されません。ただし、このトピックでは、これらのクラスターに関する提案を見つけることができます。 | |
お客様自身で保守します。 | すべてのタイプのクラスターに適用されます。 | |
クラスターアーキテクチャ
ACK クラスターは、コントロールプレーンと通常ノードまたは仮想ノードで構成されます。
コントロールプレーンは、ワークロードのスケジューリングやクラスターの状態の維持など、クラスターの管理と調整を担当します。ACK マネージドクラスターを例にとると、ACK マネージドクラスターは Kubernetes on Kubernetes アーキテクチャを採用して、API サーバー、etcd、Kubernetes スケジューラなどのコントロールプレーンコンポーネントをホストします。
ACK クラスターは、Elastic Compute Service (ECS) ノード (通常ノード) と仮想ノードをサポートしています。これらのノードは、ワークロードの実行と、ポッドの実行に必要なリソースの提供を担当します。
クラスターの HA を確保するために、複数ゾーンに ACK クラスターをデプロイできます。次の図は、ACK マネージドクラスターのアーキテクチャを示しています。
コントロールプレーンアーキテクチャ HA
ACK マネージドクラスター (Basic 版と Pro 版)、Serverless Kubernetes クラスター (Basic 版と Pro 版)、ACK Edge クラスター、および ACK Lingjun クラスターのコントロールプレーンとコントロールプレーンコンポーネント ( kube-apiserver 、etcd、 kube-scheduler など) は、ACK によって管理されます。
マルチゾーン HA:各マネージドコンポーネントは、複数ゾーンに均等に分散された複数のレプリケートポッドで実行され、ゾーンまたはノードがダウンした場合でもクラスターが想定どおりに機能し続けるようにします。
シングルゾーン HA:各マネージドコンポーネントは、複数のノードに分散された複数のレプリケートポッドで実行され、ノードがダウンした場合でもクラスターが想定どおりに機能し続けるようにします。
etcd には少なくとも 3 つのレプリケートポッドが必要であり、API サーバーには少なくとも 2 つのレプリケートポッドが必要です。Elastic Network Interface (ENI) は API サーバーのレプリケートポッドにマウントされ、ポッドはクラスターの Virtual Private Cloud (VPC) と通信できます。ノード上の kubelet と kube-proxy は、API サーバーの Classic Load Balancer (CLB) インスタンスまたは ENI を介して API サーバーに接続されます。
ACK の主要なマネージドコンポーネントは、実際の CPU とメモリの使用量に基づいてスケーリングでき、API サーバーのリソース需要に動的に対応して SLA を保証します。
コントロールプレーンで使用されるデフォルトのマルチゾーン HA アーキテクチャに加えて、「ノードプールと仮想ノードの HA 構成」、「ワークロード HA 構成」、「ロードバランサー HA 構成」、および「推奨コンポーネント構成」のセクションを参照して、データプレーン HA アーキテクチャを使用することもできます。
ノードプールと仮想ノードの HA 構成
ACK クラスターは、ECS ノード (通常ノード) と仮想ノードをサポートしています。ノードを異なるノードプールに追加し、ノードプールごとにノードをアップグレード、スケーリング、または保守できます。ビジネスが変動しない場合、または変動が予測可能な場合は、ECS ノードを使用できます。ビジネスが頻繁に変動し、変動を予測するのが難しい場合は、仮想ノードを使用してトラフィックの急増に対応し、コンピューティングコストを削減することをお勧めします。詳細については、「ノードプール」、「マネージドノードプールの概要」、および「仮想ノード」をご参照ください。
ノードプール HA 構成
ノードの自動スケーリング、デプロイメントセット、マルチゾーンデプロイメントを Kubernetes スケジューラのトポロジスプレッド制約とともに使用して、さまざまな障害ドメインでのリソース供給を確保し、単一障害点を分離できます。これにより、障害ドメインがダウンした場合のサービス継続性が確保され、単一障害点のリスクが軽減され、システム全体の信頼性と可用性が向上します。
ノードの自動スケーリングを構成する
各ノードプールはスケーリンググループに対応しています。ノードプール内のノードは、ワークロードのスケジューリングまたはクラスターリソースに基づいて手動または自動でスケーリングでき、リソースコストを削減し、エラスティックコンピューティングリソースを柔軟に割り当てることができます。ACK が提供する自動スケーリングソリューションの詳細については、「自動スケーリング」および「ノードの自動スケーリングを有効にする」をご参照ください。
デプロイメントセットを有効にする
デプロイメントセットは、ECS インスタンスの分散を制御するために使用されるポリシーです。デプロイメントセットは、ECS インスタンスをさまざまな物理サーバーに分散させ、物理サーバーがダウンした場合に物理サーバー上のすべての ECS インスタンスがシャットダウンされるのを防ぎます。ノードプールにデプロイメントセットを指定して、ノードプールに追加された ECS インスタンスがさまざまな物理サーバーに分散されるようにすることができます。次に、アフィニティルールを追加して、アプリケーションポッドが基盤となるノードトポロジを認識し、ポッドをさまざまなノードに順番に分散させることができます。これにより、アプリケーションの高可用性が確保され、大きな混乱から回復できます。デプロイメントセットを有効にする方法の詳細については、「デプロイメントセットをノードプールに関連付けるためのベストプラクティス」をご参照ください。
マルチゾーンデプロイメントを構成する
ACK はマルチゾーンノードプールをサポートしています。ノードプールを作成または実行する場合は、ノードプールに異なるゾーンにある vSwitch を選択し、[スケーリングポリシー] を [分散バランシング] に設定することをお勧めします。こうすることで、ECS インスタンスをスケーリンググループのゾーン (VPC 内の vSwitch) に分散させることができます。インベントリが不足しているためにゾーン間のリソースの分散のバランスをとることができない場合は、バランシング操作を実行できます。自動スケーリングポリシーの構成方法の詳細については、「手順 2:自動スケーリングが有効になっているノードプールを構成する」をご参照ください。

トポロジスプレッド制約を有効にする
ノードの自動スケーリング、デプロイメントセット、マルチゾーンデプロイメントを Kubernetes スケジューラの トポロジスプレッド制約 とともに使用して、さまざまなレベルで障害ドメインを分離できます。トポロジ関連のラベルは、 kubernetes.io/hostname 、 topology.kubernetes.io/zone 、 topology.kubernetes.io/region など、ACK ノードプール内のノードに自動的に追加されます。トポロジスプレッド制約を使用して、障害ドメイン間のポッドの分散を制御し、インフラストラクチャのフォールトトレランス機能を強化できます。
ACK クラスターでトポロジ対応スケジューリングを使用する方法の詳細については、「トポロジ対応スケジューリング」をご参照ください。たとえば、この機能を使用して、複数のトポロジドメイン間でポッドスケジューリングを再試行したり、低レイテンシのデプロイメントセット内の ECS インスタンスにポッドをスケジュールしたりできます。
仮想ノード HA 構成
仮想ノードを使用して、ポッドをエラスティックコンテナインスタンスにすばやくスケジュールできます。Elastic Container Instance を使用すると、ECS インスタンスを購入または管理する必要がなくなり、インフラストラクチャの保守ではなくアプリケーション開発に集中できます。ビジネス要件に合わせてエラスティックコンテナインスタンスを作成できます。リソースの使用量に対して秒単位で課金されます。
トラフィックの急増に対応するためにビジネスを水平方向にスケーリングする場合、またはジョブを処理するために多数のインスタンスを起動する場合、指定したタイプのインスタンスの在庫切れや vSwitch IP アドレスの枯渇などの問題が発生する可能性があります。その結果、システムはエラスティックコンテナインスタンスを作成できません。ACK Serverless クラスターのマルチゾーンデプロイメント機能は、エラスティックコンテナインスタンスの作成の成功率を効率的に向上させることができます。
仮想ノードで eci プロファイルを構成して、異なるゾーンの vSwitch を指定し、マルチゾーンデプロイメントを実装できます。
エラスティックコンテナインスタンスは、ポッド作成リクエストを指定されたすべての vSwitch に分散します。これにより、負荷が分散されます。
ポッドの作成に必要なリソースが vSwitch で在庫切れになった場合、システムは自動的に別の vSwitch に切り替えます。
次のコマンドを実行して、kube-system/eci-profile ConfigMap の vSwitchIds フィールドに 1 つ以上の vSwitch ID を指定します。vSwitch ID はコンマ (,) で区切ります。変更はすぐに有効になります。詳細については、「複数ゾーンを構成してポッドを作成する」をご参照ください。
kubectl -n kube-system edit cm eci-profileapiVersion: v1
data:
kube-proxy: "true" // kube-proxy を有効にする
privatezone: "true" // プライベートゾーンを有効にする
quota-cpu: "192000" // CPU クォータ
quota-memory: 640Ti // メモリクォータ
quota-pods: "4000" // ポッドクォータ
regionId: cn-hangzhou // リージョン ID
resourcegroup: "" // リソースグループ
securitygroupId: sg-xxx // セキュリティグループ ID
vpcId: vpc-xxx // VPC ID
vSwitchIds: vsw-xxx,vsw-yyy,vsw-zzz // vSwitch ID
kind: ConfigMap
ワークロード HA 構成
ワークロードの HA により、例外が発生した場合でも、アプリケーションポッドが想定どおりに実行され続けたり、すぐに回復したりできます。トポロジスプレッド制約、ポッドアンチアフィニティ、PodDisruptionBudget、ポッドヘルスチェック、ポッド自動回復を使用して、アプリケーションポッドの HA を確保できます。
トポロジスプレッド制約を構成する
トポロジスプレッド制約 は、Kubernetes クラスター内のポッドの分散を制御するために使用されます。トポロジスプレッド制約を使用して、ポッドをノードとゾーンに均等に分散させ、アプリケーションの可用性と安定性を向上させることができます。この機能は、Deployment、StatefulSet、DaemonSet、Job、および CronJob に適用されます。
maxSkew.topologyKey を構成してポッドの分散を制御し、想定されるトポロジに基づいてポッドをデプロイできます。たとえば、指定されたワークロードのポッドをゾーンに均等に分散させて、アプリケーションの可用性と信頼性を向上させることができます。例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-run-per-zone // デプロイメント名
spec:
replicas: 3 // レプリカ数
selector:
matchLabels:
app: app-run-per-zone // アプリケーションラベル
template:
metadata:
labels:
app: app-run-per-zone // アプリケーションラベル
spec:
containers:
- name: app-container // コンテナ名
image: app-image // イメージ名
topologySpreadConstraints: // トポロジスプレッド制約
- maxSkew: 1 // 最大スキュー
topologyKey: "topology.kubernetes.io/zone" // トポロジキー
whenUnsatisfiable: DoNotSchedule // 制約を満たせない場合の動作
ポッドアンチアフィニティを構成する
ポッドアンチアフィニティは、Kubernetes クラスターで使用されるスケジューリングポリシーです。このポリシーにより、ポッドが同じノードにスケジュールされないようにします。これにより、アプリケーションの可用性が向上し、障害分離機能が強化されます。例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-run-per-node // デプロイメント名
spec:
replicas: 3 // レプリカ数
selector:
matchLabels:
app: app-run-per-node // アプリケーションラベル
template:
metadata:
labels:
app: app-run-per-node // アプリケーションラベル
spec:
containers:
- name: app-container // コンテナ名
image: app-image // イメージ名
affinity: // アフィニティ設定
podAntiAffinity: // ポッドアンチアフィニティ
requiredDuringSchedulingIgnoredDuringExecution: // スケジューリング時に必須、実行時には無視
- labelSelector:
matchExpressions:
- key: app // ラベルキー
operator: In // オペレーター
values:
- app-run-per-node // ラベル値
topologyKey: "kubernetes.io/hostname" // トポロジキー
トポロジスプレッド制約を構成して、各ノードで 1 つのポッドのみを実行することもできます。 topologyKey: "kubernetes.io/hostname" が指定されている場合、各ノードはトポロジドメインとして扱われます。
次の例では、 maxSkew が 1 に設定され、 topologyKey が "kubernetes.io/hostname" に設定され、 whenUnsatisfiable が DoNotSchedule を使用するトポロジスプレッド制約を作成します。この構成では、トポロジドメイン (ノード) 間のポッドの最大スキューを 1 に制限することで、高可用性ポッド分散が適用され、スキューを維持できない場合はスケジューリングが行われないようにします。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app // デプロイメント名
spec:
replicas: 3 // レプリカ数
selector:
matchLabels:
app: my-app // アプリケーションラベル
template:
metadata:
labels:
app: my-app // アプリケーションラベル
spec:
containers:
- name: my-app-container // コンテナ名
image: my-app-image // イメージ名
topologySpreadConstraints: // トポロジスプレッド制約
- maxSkew: 1 // 最大スキュー
topologyKey: "kubernetes.io/hostname" // トポロジキー
whenUnsatisfiable: DoNotSchedule // 制約を満たせない場合の動作
PodDisruptionBudget を構成する
PodDisruptionBudget を構成して、アプリケーションの可用性をさらに向上させることができます。PodDisruptionBudget を使用すると、ノードに保持する必要があるレプリケートポッドの最小数を定義できます。ノードがメンテナンス中または障害が発生した場合、クラスターは、少なくとも指定された数のポッドがノードで引き続き実行されていることを確認します。PodDisruptionBudget を構成して、過剰な数のレプリケートポッドが同時に終了する問題を回避することもできます。PodDisruptionBudget は、複数のレプリケートポッドがデプロイされてビジネストラフィックを処理するシナリオに適しています。例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-with-pdb // デプロイメント名
spec:
replicas: 3 // レプリカ数
selector:
matchLabels:
app: app-with-pdb // アプリケーションラベル
template:
metadata:
labels:
app: app-with-pdb // アプリケーションラベル
spec:
containers:
- name: app-container // コンテナ名
image: app-container-image // イメージ名
ports:
- containerPort: 80 // コンテナポート
---
apiVersion: policy/v1beta1
kind: PodDisruptionBudget // PodDisruptionBudget
metadata:
name: pdb-for-app // PodDisruptionBudget 名
spec:
minAvailable: 2 // 最小可用ポッド数
selector:
matchLabels:
app: app-with-pdb // アプリケーションラベル
ポッドヘルスチェックとポッド自動回復を構成する
liveness プローブ、readiness プローブ、スタートアッププローブを使用して、コンテナの状態と可用性を監視および管理できます。これを行うには、プローブと再起動ポリシーをポッドの構成に追加します。例:
apiVersion: v1
kind: Pod
metadata:
name: app-with-probe // ポッド名
spec:
containers:
- name: app-container // コンテナ名
image: app-image // イメージ名
livenessProbe: // liveness プローブ
httpGet:
path: /health // パス
port: 80 // ポート
initialDelaySeconds: 10 // 初期遅延時間
periodSeconds: 5 // 期間
readinessProbe: // readiness プローブ
tcpSocket:
port: 8080 // ポート
initialDelaySeconds: 15 // 初期遅延時間
periodSeconds: 10 // 期間
startupProbe: // スタートアッププローブ
exec:
command:
- cat
- /tmp/ready
initialDelaySeconds: 20 // 初期遅延時間
periodSeconds: 15 // 期間
restartPolicy: Always // 再起動ポリシー
ロードバランサー HA 構成
ロードバランサーの HA は、サービスの安定性、応答時間、および障害分離機能を最適化する上で不可欠です。プライマリゾーンとセカンダリゾーンを指定し、トポロジ対応ヒントを有効にして、ロードバランサーの HA を確保できます。
CLB インスタンスのプライマリゾーンとセカンダリゾーンを指定する
CLB インスタンスは、ほとんどのリージョンでマルチゾーンデプロイメントを使用して、リージョン内のクロスデータセンターディザスタリカバリを実装します。サービスアノテーションを追加して、CLB インスタンスのプライマリゾーンとセカンダリゾーンを指定し、プライマリゾーンとセカンダリゾーンがノードプール内の ECS ノードのゾーンと同じであることを確認できます。これにより、ゾーン間のデータ転送が削減され、ネットワーク通信が高速化されます。CLB をサポートするリージョンとゾーンの詳細については、「CLB が利用可能なリージョン」をご参照ください。CLB インスタンスのプライマリゾーンとセカンダリゾーンを指定する方法の詳細については、「CLB インスタンスを作成するときにプライマリゾーンとセカンダリゾーンを指定する」をご参照ください。
例:
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-master-zoneid: "cn-hangzhou-a" // プライマリゾーン ID
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-slave-zoneid: "cn-hangzhou-b" // セカンダリゾーン ID
name: nginx // サービス名
namespace: default // 名前空間
spec:
ports:
- port: 80 // ポート
protocol: TCP // プロトコル
targetPort: 80 // ターゲットポート
selector:
run: nginx // セレクター
type: LoadBalancer // サービスの種類
トポロジ対応ヒントを有効にする
ゾーン間のデータ転送を削減し、ネットワーク通信を高速化するために、Kubernetes 1.23 でトポロジ対応ルーティング (トポロジ対応ヒントとも呼ばれます) が導入され、トポロジ対応の近接ルーティングがサポートされています。
この機能はサービスで使用できます。この機能が有効になっている場合、ゾーンに十分なエンドポイントがある場合、EndpointSlice コントローラーは、EndpointSlice のトポロジヒントに基づいて、トラフィックのソースに最も近いエンドポイントにトラフィックをルーティングします。ゾーン間の通信シナリオでは、この機能は、同じリージョン内でトラフィックを優先的にルーティングして、コストを削減し、データ転送効率を向上させます。詳細については、「Topology Aware Routing」をご参照ください。
推奨コンポーネント構成
ACK はさまざまなコンポーネントを提供します。新しく作成されたクラスターまたは既存のクラスターにコンポーネントをデプロイして、クラスターの機能を拡張できます。ACK コンポーネントとリリースノートの詳細については、「コンポーネントのリリースノート」をご参照ください。コンポーネントの更新、構成、アンインストール方法の詳細については、「コンポーネントの管理」をご参照ください。
NGINX Ingress コントローラーを適切にデプロイする
NGINX Ingress コントローラーをデプロイする場合は、コントローラーポッドが異なるノードに分散されていることを確認してください。これは、コントローラーポッド間のリソース競合を防ぎ、単一障害点を回避するのに役立ちます。コントローラーポッドを排他的ノードにスケジュールして、NGINX Ingress コントローラーのパフォーマンスと安定性を確保できます。詳細については、「排他的ノードを使用して NGINX Ingress コントローラーのパフォーマンスと安定性を確保する」をご参照ください。
NGINX Ingress コントローラーポッドにリソース制限を設定しないことをお勧めします。これは、メモリ不足 (OOM) エラーによって発生するサービス中断を防ぐのに役立ちます。リソース制限が必要な場合は、CPU 制限を 1,000 ミリコア以上に設定し、メモリ制限を 2 GiB 以上に設定することをお勧めします。YAML ファイルの CPU 制限は、1000m 形式で指定する必要があります。NGINX Ingress コントローラーの構成方法の詳細については、「NGINX Ingress コントローラーのベストプラクティス」をご参照ください。
Application Load Balancer (ALB) Ingress コントローラーまたは Microservices Engine (MSE) Ingress コントローラーを作成する場合は、複数ゾーンを指定することをお勧めします。詳細については、「クラウドネイティブゲートウェイを作成する」および「ALB Ingress を作成する」をご参照ください。さまざまな Ingress コントローラーの違いの詳細については、「Nginx Ingress、ALB Ingress、MSE Ingress の比較」をご参照ください。
CoreDNS を適切にデプロイする
単一障害点を回避するために、CoreDNS ポッドをさまざまなゾーンとノードに分散させることをお勧めします。デフォルトでは、CoreDNS に弱いノードアンチアフィニティが構成されています。ノードリソースが不足しているため、一部またはすべての CoreDNS ポッドが同じノードにスケジュールされる場合があります。この問題が発生した場合は、ポッドを削除してから再スケジュールします。
CoreDNS ポッドは、CPU とメモリのリソースが完全に使用されているクラスターノードにデプロイしないでください。そうしないと、DNS QPS と応答時間に悪影響が及びます。CoreDNS の構成方法の詳細については、「DNS サービスのベストプラクティス」をご参照ください。
参考資料
高仕様の ECS インスタンスにワーカーノードを作成することをお勧めします。詳細については、「ACK クラスターの ECS 仕様の推奨事項」をご参照ください。
大規模な ACK Pro マネージドクラスター (たとえば、クラスターに 500 を超えるノードまたは 10,000 を超えるポッドが含まれている場合) を使用する場合は、「大規模クラスターの使用に関する推奨事項」トピックの推奨事項をご覧ください。
ノードとノードプールのベストプラクティスの詳細については、「ノードとノードプールのベストプラクティス」をご参照ください。
自動スケーリングのベストプラクティスの詳細については、「自動スケーリングのベストプラクティス」をご参照ください。