ノードとアベイラビリティーゾーンにワークロードを分散する - AWS 規範ガイダンス

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

ノードとアベイラビリティーゾーンにワークロードを分散する

アベイラビリティーゾーンやノードなどの障害ドメイン間でワークロードを分散すると、コンポーネントの可用性が向上し、水平方向にスケーラブルなアプリケーションの障害が発生する可能性が低くなります。以下のセクションでは、ノードとアベイラビリティーゾーンにワークロードを分散する方法について説明します。

ポッドトポロジのスプレッド制約を使用する

Kubernetes ポッドトポロジの分散制約により、Kubernetes スケジューラは ReplicaSet または StatefulSet によって管理されているポッドを異なる障害ドメイン (アベイラビリティーゾーン、ノード、ハードウェアのタイプ) に分散するように指示されます。ポッドトポロジのスプレッド制約を使用すると、次のことができます。

  • アプリケーションの要件に応じて、さまざまな障害ドメインにポッドを分散または集中させます。たとえば、レジリエンスのためにポッドを配布し、ネットワークパフォーマンスのためにポッドを集中させることができます。

  • アベイラビリティーゾーン間での分散やノード間での分散など、さまざまな条件を組み合わせます。

  • 条件が満たされない場合は、優先アクションを指定します。

    • maxSkew と の組み合わせwhenUnsatisfiable: DoNotScheduleminDomainsを使用して、スケジューラのハード要件を作成します。

    • whenUnsatisfiable: ScheduleAnyway を使用して を減らしますmaxSkew

障害ゾーンが使用できなくなった場合、そのゾーンのポッドは異常になります。Kubernetes は、可能であればスプレッド制約に準拠しながらポッドを再スケジュールします。

ポッドトポロジの分散制約

次のコードは、アベイラビリティーゾーン間またはノード間でポッドトポロジースプレッド制約を使用する例を示しています。

... spec: selector: matchLabels: app: <your-app-label> replicas: 3 template: metadata: labels: <your-app-label> spec: serviceAccountName: <ServiceAccountName> ... topologySpreadConstraints: - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: topology.kubernetes.io/zone # <---spread those pods evenly over all availability zones whenUnsatisfiable: ScheduleAnyway - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: kubernetes.io/hostname # <---spread those pods evenly over all nodes whenUnsatisfiable: ScheduleAnyway

クラスター全体のトポロジのデフォルトの分散制約

すぐに使用できる Kubernetes には、ノードとアベイラビリティーゾーン間でポッドを分散するためのトポロジースプレッド制約のデフォルトセットが用意されています。

defaultConstraints: - maxSkew: 3 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: ScheduleAnyway - maxSkew: 5 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway
注記

さまざまなタイプのトポロジ制約を必要とするアプリケーションは、クラスターレベルのポリシーを上書きできます。

デフォルトの制約は高い を設定します。これはmaxSkew、少数のポッドを持つデプロイには役に立ちません。現時点では、Amazon EKS では KubeSchedulerConfiguration を変更できません。他のトポロジスプレッド制約のセットを適用する必要がある場合は、以下のセクションのように変更アドミッションコントローラーを使用することを検討してください。代替スケジューラを実行する場合は、デフォルトのトポロジスプレッド制約を制御することもできます。ただし、カスタムスケジューラを管理すると複雑さが増し、クラスターの耐障害性と HA に影響する可能性があります。このような理由から、トポロジの分散制約にのみ代替スケジューラを使用することはお勧めしません。

トポロジスプレッド制約のゲートキーパーポリシー

トポロジの分散制約を適用するもう 1 つのオプションは、Gatekeeper プロジェクトのポリシーを使用することです。ゲートキーパーポリシーはアプリケーションレベルで定義されます。

次のコード例は、デプロイ用のGatekeeper OPAポリシーの使用を示しています。必要に応じてポリシーを変更できます。たとえば、 というラベルのデプロイにのみポリシーを適用するかHA=true、別のポリシーコントローラーを使用して同様のポリシーを記述します。

この最初の例は、 ConstraintTemplateで使用される を示していますk8stopologyspreadrequired_template.yml

apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8stopologyspreadrequired spec: crd: spec: names: kind: K8sTopologySpreadRequired validation: openAPIV3Schema: type: object properties: message: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8stopologyspreadrequired get_message(parameters, _default) =3D msg { not parameters.message msg :=_default } get_message(parameters, _default) =3D msg { msg := parameters.message } violation[{"msg": msg}] { input.review.kind.kind ="Deployment" not input.review.object.spec.template.spec.topologySpreadConstraint def_msg :"Pod Topology Spread Constraints are required for Deployments" msg :get_message(input.parameters, def_msg) }

次のコードは、YAML constraints マニフェスト を示していますk8stopologyspreadrequired_constraint.yml

apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sTopologySpreadRequired metadata: name: require-topologyspread-for-deployments spec: match: kinds: - apiGroups: ["apps"] kinds: ["Deployment"] namespaces: ## Without theses two lines will apply to the whole cluster - "example"

トポロジスプレッド制約を使用するタイミング

以下のシナリオでは、トポロジースプレッド制約の使用を検討してください。

  • 水平方向にスケーラブルなアプリケーション (ステートレスウェブサービスなど)

  • アクティブ/アクティブまたはアクティブ/パッシブレプリカを持つアプリケーション (NoSQL データベースやキャッシュなど)

  • スタンバイレプリカを持つアプリケーション (コントローラーなど)

水平方向にスケーラブルなシナリオに使用できるシステムコンポーネントには、次のようなものがあります。

ポッドアフィニティとアンチアフィニティ

場合によっては、特定のタイプのポッドがノードで実行されないようにすることが有益です。たとえば、同じノードで複数のネットワーク負荷の高いポッドをスケジュールしないようにするには、ラベル Ingressまたは でアンチアフィニティルールを使用できますNetwork-heavy。を使用する場合はanti-affinity、次の組み合わせを使用することもできます。

  • ネットワーク最適化ノードのテイント

  • ネットワーク負荷の高いポッドでの対応する許容範囲

  • ネットワーク負荷の高いポッドがネットワーク最適化インスタンスを使用するようにするためのノードアフィニティまたはノードセレクタ

ネットワーク負荷の高いポッドが例として使用されます。GPU、メモリ、ローカルストレージなど、要件が異なる場合があります。その他の使用例と設定オプションについては、Kubernetes ドキュメントを参照してください。

ポッドの再調整

このセクションでは、Kubernetes クラスター内のポッドを再調整するための 2 つのアプローチについて説明します。1 つ目は Descheduler for Kubernetes を使用します。Descheduler は、トポロジスプレッド制約またはアンチアフィニティルールに違反するポッドを削除する戦略を強制することで、ポッド分散を維持するのに役立ちます。2 番目のアプローチでは、Karpenter 統合とビンパッキング機能を使用します。統合は、ワークロードをより少なく、より効率的にパックされたノードに統合することで、リソースの使用状況を継続的に評価して最適化します。

Karpenter を使用していない場合は、Descheduler を使用することをお勧めします。Karpenter と Cluster Autoscaler を一緒に使用している場合は、ノードグループに Descheduler と Cluster Autoscaler を使用できます。

グループレスノードのデスケジューラ

ポッドが削除されてもトポロジの制約が満たされ続ける保証はありません。たとえば、デプロイをスケールダウンすると、ポッド分散が不均衡になる可能性があります。ただし、Kubernetes はスケジューリング段階でのみポッドトポロジの分散制約を使用するため、ポッドは障害ドメイン間で不均衡のままになります。

このようなシナリオでバランスの取れたポッドディストリビューションを維持するには、Descheduler for Kubernetes を使用できます。デスケジューラは、ポッドの最大有効期間や有効期限 (TTL) の適用やインフラストラクチャの使用の改善など、複数の目的に便利なツールです。レジリエンスと高可用性 (HA) の観点から、次のデスケジューラ戦略を検討してください。

Karpenter 統合とビンパッキング機能

Karpenter を使用するワークロードでは、統合機能とビンパッキング機能を使用してリソース使用率を最適化し、Kubernetes クラスターのコストを削減できます。Karpenter は、ポッドの配置とノード使用率を継続的に評価し、可能であればワークロードをより少なく、より効率的にパックされたノードに統合しようとします。このプロセスでは、リソース要件を分析し、ポッドアフィニティルールなどの制約を考慮し、ノード間でポッドを移動して全体的なクラスター効率を向上させる可能性があります。次のコードは例を示しています。

apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: name: default spec: disruption: consolidationPolicy: WhenUnderutilized expireAfter: 720h

ではconsolidationPolicyWhenUnderutilizedまたは を使用できますWhenEmpty

  • consolidationPolicy が に設定されている場合WhenUnderutilized、Karpenter はすべてのノードを統合と見なします。Karpenter が空または十分に使用されていないノードを検出すると、Karpenter はコストを削減するためにノードの削除または交換を試みます。

  • consolidationPolicy が に設定されている場合WhenEmpty、Karpenter はワークロードポッドを含まないノードのみを統合対象と見なします。

Karpenter の統合の決定は、モニタリングツールに表示される CPU またはメモリ使用率のみに基づくものではありません。代わりに、Karpenter はポッドリソースリクエストと潜在的なコスト最適化に基づいて、より複雑なアルゴリズムを使用します。詳細については、Karpenter のドキュメントを参照してください。