高可用性 (HA) は、サービスの信頼性と継続性を保証するシステム設計です。 Container Service for Kubernetes (ACK) は、Kubernetesアーキテクチャに基づくさまざまなクラスターHAメカニズムを提供し、コントロールプレーン、ノード、ノードプール、ワークロード、およびロードバランサーの高可用性を確保します。 これにより、安定した、安全で信頼性の高いクラスターおよびアプリケーションアーキテクチャを構築できます。
このトピックについて
このトピックは、ACKクラスターの開発者および管理者を対象としています。 このトピックの提案は、HAクラスターの計画と作成に役立ちます。Container Service for Kubernetes実際の設定は、クラスターの環境とビジネスによって異なる場合があります。 このトピックでは、コントロールプレーンとデータプレーンの推奨HA設定を参照できます。
設定 | によって維持される | 適用可能なクラスタータイプ |
ACKによって維持されます。 | 次のACKクラスターにのみ適用できます。ACKマネージドクラスター (BasicおよびProエディション) 、ACKサーバーレスクラスター (BasicおよびProエディション) 、ACK Edgeクラスター、ACK Lingjunクラスター。 ACK専用クラスターや登録済みクラスターなど、他のクラスターの制御プレーンを維持する必要があります。 したがって、制御プレーンアーキテクチャHAは、これらのクラスタには適用できない。 ただし、このトピックでは、これらのクラスターの提案を見つけることができます。 | |
あなたによって維持されます。 | すべてのタイプのクラスターに適用できます。 | |
クラスターアーキテクチャ
ACKクラスタは、制御プレーンおよび通常ノードまたは仮想ノードからなる。
コントロールプレーンは、ワークロードのスケジューリングやクラスタステータスのメンテナンスなど、クラスタの管理と調整を担当します。 例として、ACK管理クラスターを取り上げます。 ACKマネージドクラスターは、Kubernetes on Kubernetesアーキテクチャを採用して、APIサーバー、etcd、Kubernetesスケジューラなどの制御プレーンコンポーネントをホストします。
ACKクラスターは、ECS (Elastic Compute Service) ノード (通常ノード) と仮想ノードをサポートしています。 これらのノードは、ワークロードの実行とポッドの実行に必要なリソースの提供を担当します。
複数のゾーンにACKクラスターをデプロイして、クラスターのHAを確保できます。 次の図は、ACK管理クラスターのアーキテクチャを示しています。
制御プレーンアーキテクチャHA
ACKマネージドクラスター (BasicおよびProエディション) 、ACKサーバーレスクラスター (BasicおよびProエディション) 、ACK Edgeクラスター、ACK Lingjunクラスターの制御プレーンおよび制御プレーンコンポーネント (APIサーバー、etcd、Kubernetesスケジューラなど) は、ACKによって管理されます。
マルチゾーンHA: 各マネージドコンポーネントは、複数のゾーンに均等に分散された複数のレプリケートされたポッドで実行され、ゾーンまたはノードがダウンしてもクラスターが期待どおりに機能できるようにします。
シングルゾーンHA: 各マネージドコンポーネントは、複数のノードに分散された複数のレプリケートされたポッドで実行され、ノードがダウンしてもクラスターが期待どおりに機能できるようにします。
etcdには少なくとも3つのレプリケートポッドが必要で、APIサーバーには少なくとも2つのレプリケートポッドが必要です。 Elastic network Interface (ENI) は、APIサーバーのレプリケートされたポッドにマウントされているため、ポッドはクラスターの仮想プライベートクラウド (VPC) と通信できます。 ノード上のkubeletおよびkube-proxyは、APIサーバーまたはENIのClassic Load Balancer (CLB) インスタンスを介してAPIサーバーに接続されます。
ACKの鍵管理コンポーネントは、実際のCPUおよびメモリ使用量に基づいてスケーリングして、SLAを保証するためにAPIサーバのリソース要求を動的に満たすことができる。
コントロールプレーンで使用されるデフォルトのマルチゾーン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コンテナインスタンスにすばやくスケジュールできます。 Elastic Container Instanceにより、ECSインスタンスを購入または管理する必要がなくなり、インフラストラクチャのメンテナンスではなくアプリケーション開発に集中できます。 ビジネス要件を満たすelasticコンテナインスタンスを作成できます。 リソースの使用量は1秒ごとに課金されます。
トラフィックの急増に対処するためにビジネスを水平スケールしたり、ジョブを処理するために多数のインスタンスを起動したりすると、指定されたタイプのインスタンスが在庫切れになったり、vSwitchのIPアドレスが使い果たされたりするなどの問題が発生する可能性があります。 その結果、システムはエラスティックコンテナインスタンスを作成できません。 ACKサーバーレスクラスターのマルチゾーンデプロイ機能により、柔軟なコンテナインスタンス作成の成功率を効率的に向上させることができます。
仮想ノードでeci-profilesを構成して、異なるゾーンでvSwitchを指定し、マルチゾーン展開を実装できます。
エラスティックコンテナインスタンスは、指定されたすべてのvSwitchにポッド作成要求を配信します。 これは負荷のバランスをとる。
ポッドの作成に必要なリソースがvSwitchで在庫切れの場合、システムは自動的に別のvSwitchに切り替わります。
次のコマンドを実行して、kube-system/eci-profile ConfigMapのvSwitchIds
フィールドに1つ以上のvSwitch IDを指定します。 vSwitch IDはコンマ (,) で区切ります。 変更内容はすぐに有効になります。 詳細については、「ゾーン間のECIの作成」をご参照ください。
kubectl -n kube-system edit cm eci-profile
apiVersion: v1
data:
kube-proxy: "true"
privatezone: "true"
quota-cpu: "192000"
quota-memory: 640Ti
quota-pods: "4000"
regionId: cn-hangzhou
resourcegroup: ""
securitygroupId: sg-xxx
vpcId: vpc-xxx
vSwitchIds: vsw-xxx,vsw-yyy,vsw-zzz
kind: ConfigMap
ワークロードHA設定
ワークロードのHAは、アプリケーションポッドが期待どおりに実行されるか、例外が発生したときに迅速に回復できるようにします。 トポロジスプレッドの制約、ポッドのアンチアフィニティ、ポッドの中断予算、ポッドのヘルスチェック、ポッドの自動回復を使用して、アプリケーションポッドのHAを確保できます。
トポロジ拡散制約の設定
トポロジスプレッド制約は、Kubernetesクラスター内のポッドの分布を制御するために使用されます。 トポロジスプレッド制約を使用して、ポッドをノードとゾーンに均等に分散させ、アプリケーションの可用性と安定性を向上させることができます。 この機能は、Deployments、StatefuSets、DaemonSets、Jobs、およびCronJobsに適用されます。
予想されるトポロジに基づいてポッドをデプロイするために、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
pod anti-affinityの設定
ポッドアンチアフィニティは、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つのポッドのみをホストできます。 これにより、スケジューラはノード間にポッドを拡散してHAを確保します。
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
ポッド破壊予算の設定
ポッド破壊予算を設定して、アプリケーションの可用性をさらに向上させることができます。 ポッドの中断バジェットを使用すると、ノードに保持する必要があるレプリケートされたポッドの最小数を定義できます。 ノードがメンテナンス中または障害が発生している場合、クラスターはノードで指定された数以上のポッドが実行されていることを確認します。 また、過剰な数のレプリケートされたポッドが同時に終了する問題を回避するために、ポッドの中断予算を設定することもできます。 ポッドの混乱予算は、複数のレプリケートされたポッドを展開してビジネストラフィックを処理するシナリオに適しています。 例:
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
metadata:
name: pdb-for-app
spec:
minAvailable: 2
selector:
matchLabels:
app: app-with-pdb
ポッドのヘルスチェックとポッドの自動復旧の設定
コンテナーのステータスと可用性を監視および管理するには、次のタイプのプローブを使用できます。 これを行うには、ポッドの設定にプローブと再起動ポリシーを追加します。 例:
apiVersion: v1
kind: Pod
metadata:
name: app-with-probe
spec:
containers:
- name: app-container
image: app-image
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
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"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-slave-zoneid: "cn-hangzhou-b"
name: nginx
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
type: LoadBalancer
トポロジ認識ヒントの有効化
ゾーン間のデータ転送を削減し、ネットワーク通信を高速化するために、トポロジ認識ルーティング (トポロジ認識ヒントとも呼ばれます) がKubernetes 1.23に導入され、トポロジ認識近隣ルーティングをサポートしています。
この機能はサービスで使用できます。 この機能を有効にした後、ゾーンに十分なエンドポイントがある場合、EndpointSliceコントローラーは、EndpointSliceのトポロジヒントに基づいて、トラフィックのソースに最も近いエンドポイントにトラフィックをルーティングします。 ゾーン間通信シナリオでは、この機能は、コストを削減し、データ転送効率を向上させるために、同じリージョン内でトラフィックをルーティングすることが望ましい。 詳細については、「トポロジ認識のルーティング」をご参照ください。
推奨コンポーネント構成
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ポッドを異なるゾーンとノードに分散することを推奨します。 デフォルトでは、weak node anti-affinityはCoreDNS用に設定されています。 ノードリソースが不十分なため、一部またはすべてのCoreDNSポッドが同じノードにスケジュールされる場合があります。 この問題が発生した場合は、ポッドを削除してから再スケジュールします。
CoreDNSポッドは、CPUとメモリリソースが完全に利用されているクラスターノードにデプロイしないでください。 そうでない場合、DNS QPSおよび応答時間は悪影響を受ける。 CoreDNSの設定方法の詳細については、「DNSサービスのベストプラクティス」をご参照ください。
関連ドキュメント
仕様の高いECSインスタンスにワーカーノードを作成することを推奨します。 詳細については、「ACKクラスターのECS仕様の選択に関する提案」をご参照ください。
たとえば、大規模なACK Proクラスターを使用している場合、クラスターに500を超えるノードまたは10,000ポッドが含まれている場合は、「大規模クラスターの使用に関する提案」トピックで提案を表示します。
ノードとノードプールのベストプラクティスの詳細については、「ノードとノードプールのベストプラクティス」をご参照ください。
自動スケーリングのベストプラクティスの詳細については、「自動スケーリングのベストプラクティス」をご参照ください。