Cluster Autoscaler - Amazon EKS

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

Cluster Autoscaler

Kubernetes Cluster Autoscaler は、ポッドに障害が発生したとき、またはポッドが他のノードに再スケジュールされたときに、クラスター内のノード数を自動的に調整します。つまり、Kubernetes Cluster Autoscaler 内のAWSクラウドプロバイダー実装は.DesiredReplicasAuto Scaling グループの Amazon EC2 フィールドを制御します。Cluster Autoscaler は通常、クラスターにデプロイとしてインストールされます。リーダーの選択を使用して高可用性を確保しますが、スケーリングは一度に 1 つのレプリカによって行われます。

Cluster Autoscaler をデプロイする前に、Kubernetes の概念と AWS の機能の関係を理解することが重要です。このトピックでは以下の用語を使用します。

  • Kubernetes – Cluster Autoscaler スケジューリングとスケーリングの決定を行う Kubernetes コントロールプレーンのコアコンポーネント。詳細については、「 での Kubernetes コントロールプレーンに関するよくある質問」を参照してくださいGitHub。

  • AWS クラウドプロバイダーの実装 – プラットフォームと通信することによって Kubernetes AWSCluster Autoscaler の決定を実装する Kubernetes Cluster Autoscaler の拡張 (例: Amazon EC2)。詳細については、「 での AWS での Cluster Autoscaler」を参照してくださいGitHub。

  • ノードグループ – クラスター内のノードのグループの Kubernetes 抽象化。ノードグループは実際の Kubernetes リソースではありませんが、Cluster Autoscaler、Cluster API、およびその他のコンポーネントの抽象化として存在します。1 つのノードグループ内に存在するノードは、ラベルや taints などの複数のプロパティを共有する場合があります。ただし、複数の アベイラビリティーゾーンまたはインスタンスタイプで構成できます。

  • Amazon EC2 Auto Scaling – グループ Cluster Autoscaler によってAWS使用される の機能。Auto Scaling グループは、多数のユースケースに適しています。 Amazon EC2 Auto Scaling グループは、Kubernetes クラスターを自動的に結合するインスタンスを起動するように設定されています。また、Kubernetes API の対応するノードリソースにラベルと taints を適用します。

参考のために、 マネージド型ノードグループ は Amazon EC2 Auto Scaling グループを使用して実装され、Cluster Autoscaler と互換性があります。

このトピックでは、Cluster Autoscaler を Amazon EKS クラスターにデプロイし、 Amazon EC2 Auto Scaling グループを変更するように設定する方法を示します。

Prerequisites

Cluster Autoscaler をデプロイする前に、次の前提条件を満たす必要があります。

  • 既存の Kubernetes クラスターがある – クラスターがない場合はAmazon EKS クラスターの作成、「」を参照してください。

  • クラスターの既存の IAM OIDC プロバイダー。作成済みであるかどうかを確認するには、「」を参照してください。作成済みでない場合は、「」クラスターの IAM OIDC プロバイダーを作成するを参照してください。

  • Auto Scaling グループタグ付きのノードグループ – クラスター Autoscaler では、自動検出できるようにAuto Scaling、グループに次のタグが必要です。を使用してノードグループeksctlを作成した場合、これらのタグは自動的に適用されます。eksctl を使用してノードグループを作成しなかった場合は、以下のタグを使用してAuto Scaling手動でグループにタグ付けする必要があります。詳細については、の「Amazon Amazon EC2 リソースのhttps://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.htmlタグ付け」を参照してくださいLinux インスタンス用 Amazon EC2 ユーザーガイド。

    キー
    k8s.io/cluster-autoscaler/<cluster-name>

    owned

    k8s.io/cluster-autoscaler/enabled TRUE

IAM ポリシーとロールを作成する

Cluster Autoscaler が IAM ロールに必要なアクセス許可を付与する IAM ポリシーを作成します。プロシージャ全体で <example-values> ( を含む<>) を独自の値に置き換えます。

  1. IAM ポリシーを作成します。

    1. 以下の内容を という名前のファイルに保存しますcluster-autoscaler-policy.json。 既存のノードグループが で作成されeksctl--asg-access オプションを使用した場合、このポリシーはすでに存在しているため、ステップ 2 に進むことができます。

      { "Version": "2012-10-17", "Statement": [ { "Action": [ "autoscaling:DescribeAutoScalingGroups", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeLaunchConfigurations", "autoscaling:DescribeTags", "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup", "ec2:DescribeLaunchTemplateVersions" ], "Resource": "*", "Effect": "Allow" } ] }
    2. 次のコマンドを使用してポリシーを作成します。[] の値を変更できますpolicy-name

      aws iam create-policy \ --policy-name AmazonEKSClusterAutoscalerPolicy \ --policy-document file://cluster-autoscaler-policy.json

      後のステップで使用するために、出力で返される ARN を書き留めます。

  2. IAM または を使用してIAM、 ロールを作成し、 eksctl ポリシーをアタッチできますAWS マネジメントコンソール。ロールを作成するツールの名前が付いているタブを選択します。

    eksctl
    1. でクラスターを作成した場合は、次のコマンドを実行しますeksctl--asg-access オプションを使用してノードグループを作成した場合は、 を が作成した<AmazonEKSClusterAutoscalerPolicy>ポリシーの名前IAMに置き換えますeksctl。ポリシー名は のようになりますeksctl-<cluster-name>-nodegroup-ng-<xxxxxxxx>-PolicyAutoScaling

      eksctl create iamserviceaccount \ --cluster=<my-cluster> \ --namespace=kube-system \ --name=cluster-autoscaler \ --attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/<AmazonEKSClusterAutoscalerPolicy> \ --override-existing-serviceaccounts \ --approve
    2. --asg-access オプションを使用してノードグループを作成した場合は、 がノードグループIAMeksctl用にAmazon EKS ノードIAMロール作成して にアタッチしたeksctlポリシーをデタッチすることをお勧めします。ノードIAMロールからポリシーをデタッチすると、Cluster Autoscaler は正しく機能しますが、ノード上の他のポッドにポリシーのアクセス許可が付与されません。詳細については、の「IAM ID アクセス許可https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html#remove-policies-consoleの削除」を参照してくださいLinux インスタンス用 Amazon EC2 ユーザーガイド。

    AWS マネジメントコンソール
    1. IAM コンソール (https://console.aws.amazon.com/iam/) を開きます。

    2. ナビゲーションペインで [ロール]、[ロールの作成] の順に選択します。

    3. [Select type of trusted entity (信頼されたエンティティの種類を選択)] セクションで、[Web identity (ウェブ ID)] を選択します。

    4. [Choose a web identity provider (ウェブ ID プロバイダーの選択)] セクションで、以下の操作を行います。

      1. [ID プロバイダー] で、クラスターの URL を選択します。

      2. Audience (対象者)] で [sts.amazonaws.com.] を選択します。

    5. [Next: Permissions (次へ: アクセス許可)] を選択します。

    6. [ポリシーのアタッチ] セクションで、 AmazonEKSClusterAutoscalerPolicy サービスアカウントに使用するステップ 1 で作成した ポリシー。

    7. [次へ: タグ] を選択します。

    8. [Add tags (optional) (タグの追加 (オプション))] 画面で、アカウントのタグを追加できます。[次へ: 確認] を選択します。

    9. [ロール名] に、ロールの名前を入力します。またはAmazonEKSClusterAutoscalerRole, 続いて、[ロールの作成] を選択します。

    10. ロールが作成されたら、コンソールでロールを選択して編集用に開きます。

    11. [Trust relationships] タブを選択し、続いて [Edit trust relationship] を選択します。

    12. 次のような行を見つけます。

      "oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com"

      行を次の行のように変更します。<EXAMPLED539D4633E53DE1B716D3041E> ( を含む<>) をクラスターの OIDC プロバイダー ID に置き換え、 <region-code> をクラスターがあるリージョンコードに置き換えます。

      "oidc.eks.<region-code>.amazonaws.com/id/<EXAMPLED539D4633E53DE1B716D3041E>:sub": "system:serviceaccount:kube-system:cluster-autoscaler"
    13. [Update Trust Policy (信頼ポリシーの更新)] を選択して終了します。

Cluster Auto Scaling をデプロイする

Cluster Autoscaler をデプロイするには、以下の手順を実行します。本番稼働用クラスターにデプロイする前に、Cluster Autoscaler のデプロイを確認してデプロイに関する考慮事項最適化することをお勧めします。

Cluster Auto Scaling をデプロイするには

  1. Cluster Autoscaler をデプロイします。

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
  2. cluster-autoscaler サービスアカウントに、前に作成した IAM ロールの ARN を注釈として付けます。の置き換え <example values> 独自の値を使用します。

    kubectl annotate serviceaccount cluster-autoscaler \ -n kube-system \ eks.amazonaws.com/role-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:role/<AmazonEKSClusterAutoscalerRole>
  3. 次のコマンドを使用して、Cluster Autoscaler ポッドにcluster-autoscaler.kubernetes.io/safe-to-evict注釈を追加するには、デプロイにパッチを適用します。

    kubectl patch deployment cluster-autoscaler \ -n kube-system \ -p '{"spec":{"template":{"metadata":{"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"}}}}}'
  4. 次のコマンドを使用して Cluster Autoscaler デプロイを編集します。

    kubectl -n kube-system edit deployment.apps/cluster-autoscaler

    cluster-autoscaler コンテナコマンドを編集して を置き換える <YOUR CLUSTER NAME> ( を含む) <>) を選択し、以下のオプションを追加します。

    • --balance-similar-node-groups

    • --skip-nodes-with-system-pods=false

    spec: containers: - command: - ./cluster-autoscaler - --v=4 - --stderrthreshold=info - --cloud-provider=aws - --skip-nodes-with-local-storage=false - --expander=least-waste - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR CLUSTER NAME> - --balance-similar-node-groups - --skip-nodes-with-system-pods=false

    ファイルを保存して閉じ、変更を適用します。

  5. ウェブブラウザで から Cluster Autoscaler リリースGitHubページを開き、クラスターの Kubernetes メジャーバージョンとマイナーバージョンに一致する最新の Cluster Autoscaler バージョンを見つけます。たとえば、クラスターの Kubernetes バージョンが 1.19 の場合、1.19. で始まる最新の Cluster Autoscaler リリースを見つけます。次のステップで使用するために、そのリリースのセマンティックバージョン番号 (1.19.n) を記録します。

  6. 次のコマンドを使用して、Cluster Autoscaler イメージタグを、前のステップで書き留めたバージョンに設定します。置換 1.19.n 独自の値に置き換えます。

    kubectl set image deployment cluster-autoscaler \ -n kube-system \ cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v<1.19.n>

Cluster Autoscaler ログを表示する

Cluster Autoscaler をデプロイしたら、ログを表示してクラスターの負荷をモニタリングしていることを確認できます。

次のコマンドを使用して Cluster Autoscaler ログを表示します。

kubectl -n kube-system logs -f deployment.apps/cluster-autoscaler

出力:

I0926 23:15:55.165842 1 static_autoscaler.go:138] Starting main loop I0926 23:15:55.166279 1 utils.go:595] No pod using affinity / antiaffinity found in cluster, disabling affinity predicate for this loop I0926 23:15:55.166293 1 static_autoscaler.go:294] Filtering out schedulables I0926 23:15:55.166330 1 static_autoscaler.go:311] No schedulable pods I0926 23:15:55.166338 1 static_autoscaler.go:319] No unschedulable pods I0926 23:15:55.166345 1 static_autoscaler.go:366] Calculating unneeded nodes I0926 23:15:55.166357 1 utils.go:552] Skipping ip-192-168-3-111.<region-code>.compute.internal - node group min size reached I0926 23:15:55.166365 1 utils.go:552] Skipping ip-192-168-71-83.<region-code>.compute.internal - node group min size reached I0926 23:15:55.166373 1 utils.go:552] Skipping ip-192-168-60-191.<region-code>.compute.internal - node group min size reached I0926 23:15:55.166435 1 static_autoscaler.go:393] Scale down status: unneededOnly=false lastScaleUpTime=2019-09-26 21:42:40.908059094 ... I0926 23:15:55.166458 1 static_autoscaler.go:403] Starting scale down I0926 23:15:55.166488 1 scale_down.go:706] No candidates for scale down

デプロイに関する考慮事項

Cluster Autoscaler のデプロイを最適化するには、次の考慮事項を確認します。

スケーリングに関する考慮事項

Cluster Autoscaler は、ノードの追加機能を考慮するように設定できます。これらの機能には、ノードにアタッチされた Amazon EBS ボリューム、ノードのAmazon EC2インスタンスタイプ、GPU アクセラレーターなどがあります。

アベイラビリティーゾーンs

複数のノードグループを設定し、各グループを単一の に絞り込みアベイラビリティーゾーン、--balance-similar-node-groups機能を有効にすることをお勧めします。それ以外の場合は、1 つのノードグループのみを作成した場合、そのノードグループを複数の アベイラビリティーゾーンにまたがるようにスコープできます。

ノードグループの構成

Cluster Autoscaler は、グループ内で使用しているインスタンスタイプなど、ノードグループの使用方法について仮定します。これらの前提と合致するには、以下の考慮事項に基づいてノードグループを設定することが重要です。

  • ノードグループの各ノードには、ラベル、taints、リソースなどの同じスケジューリングプロパティがあります。

    • の場合MixedInstancePolicies、インスタンスタイプは CPU、メモリ、GPU で同じシェイプである必要があります。

    • ポリシーで指定された最初のインスタンスタイプは、スケジューリングをシミュレートします。

    • ポリシーに追加のインスタンスタイプがあり、より多くのリソースがある場合、スケールアウト後にリソースが無駄になる場合があります。

    • ポリシーに追加のインスタンスタイプがあり、元のインスタンスタイプよりもリソースが少ない場合、ポッドはインスタンスでスケジュールに失敗することがあります。

  • 反対方向ではなく、ノード数が多いノードグループを少なく設定することをお勧めします。これは、反対の設定がスケーラビリティに悪影響を及ぼすためです。

  • 両方のシステムがサポートを提供するときは、必ず Amazon EC2 機能を使用することをお勧めします。(たとえば、 リージョンと を使用しますMixedInstancePolicy)。

可能であれば、 を使用することをお勧めしますマネージド型ノードグループ。マネージド型ノードグループには、自動Amazon EC2Auto Scalingグループ検出や優れたノード終了などの Cluster Autoscaler の機能を含む強力な管理機能が用意されています。

EBS ボリューム

データベースや分散キャッシュなどのステートフルアプリケーションを構築するには、永続的ストレージが不可欠です。Amazon EBS ボリュームを使用すると、Kubernetes でステートフルアプリケーションを構築できますが、特定のゾーン内でこれを行うことに制限されます。詳細については、「Amazon EKS で永続的ストレージを使用する方法」を参照してください。ステートフルアプリケーションは、 ごとに別々のアベイラビリティーゾーンボリュームを使用して複数の Amazon EBS間でシャード (分割) された場合に高可用性になりますアベイラビリティーゾーン。そのため、Cluster Autoscaler はAmazon EC2Auto Scalingグループのスケーリングのバランスをとることができます。これを行うには、次の条件が満たされていることを確認します。

  • ノードグループのバランシングは、 を設定することで有効になりますbalance-similar-node-groups=true

  • ノードグループは、異なる アベイラビリティーゾーンおよび Amazon EBS ボリュームを除き、同じ設定で設定されます。

共同スケジュール

機械学習分散トレーニングジョブは、同一ゾーンのノード設定のレイテンシーを最小限に抑えることで、大幅なメリットを得られます。これらのワークロードは、特定のゾーンに複数のポッドをデプロイします。これを行うには、 を使用して、すべてのスケジュールされたポッドまたはノードのアフィニティにポッドアフィニティを設定しますtopologyKey: failure-domain.beta.kubernetes.io/zone。 この設定に基づいて、Cluster Autoscaler は需要に合わせて特定のゾーンをスケールアウトします。スケジュールされたワークロード全体のフェイルオーバーを有効にするAmazon EC2ために、 ごとに 1 つの グループを持つ複数のAuto Scalingアベイラビリティーゾーングループを割り当てることができます。次の条件が満たされていることを確認します。

  • ノードグループのバランシングを有効にするには、 を設定します。 balance-similar-node-groups=false.

  • ノードアフィニティポッドプリエンプション、またはその両方は、クラスターにリージョンノードグループとゾーンノードグループの両方が含まれている場合に使用されます。

    • ノードのアフィニティを使用して、リージョンポッドを強制または推奨し、ゾーンノードグループを回避します。

    • ゾーンポッドがリージョンノードグループにスケジュールする場合、これによりリージョンポッドの容量が不均等になります。

    • ゾーンのワークロードが中断と再配置を許容できる場合は、リージョンスケーリングされたポッドが競合の少ないゾーンで強制的にプリエンプションと再スケジュールできるように、ポッドプリエンプションを設定します。

アクセラレーターと GPUs

一部のクラスターでは、専用 GPU などの特殊なハードウェアアクセラレーターを利用します。スケールアウト時、アクセラレーターデバイスプラグインはクラスターにリソースをアドバタイズするのに数分かかる場合があります。この間、Cluster Autoscaler は、このノードに アクセラレーターがあることをシミュレートします。ただし、アクセラレーターが準備状態になり、ノードの使用可能なリソースを更新するまで、保留中のポッドをノードでスケジュールすることはできません。これにより、不要なスケールアウトhttps://github.com/kubernetes/kubernetes/issues/54959が繰り返される可能性があります。

アクセラレーターが使用されていない場合でも、アクセラレーターと高い CPU またはメモリ使用率を持つノードはスケールダウン対象にはなりません。ただし、これはコストが高くなる可能性があります。これらのコストを回避するために、Cluster Autoscaler は、アクセラレーターが未使用の場合は、スケールダウンするノードを考慮する特別なルールを適用できます。

このような場合に正しく動作するように、クラスターを結合する前にノードにラベルを付けるようにアクセラレーターノードkubeletで を設定できます。Cluster Autoscaler は、このラベルセレクタを使用して、アクセラレーターに最適化された動作を呼び出します。次の条件が満たされていることを確認します。

  • kubelet for GPU ノードは で設定されます--node-labels k8s.amazonaws.com/accelerator=$ACCELERATOR_TYPE

  • アクセラレーターを持つノードは、同じスケジューリングプロパティルールに準拠します。

ゼロからのスケーリング

Cluster Autoscaler はノードグループを 0 との間でスケーリングできるため、大幅なコスト削減につながります。Auto Scaling または InstanceType で指定された を調べることで、 LaunchConfiguration グループの CPU、メモリ、GPU リソースを検出しますLaunchTemplate。 一部のポッドでは、 WindowsENI や などの追加のリソースが必要ですPrivateIPv4Address。またNodeSelectors、特定の Taints や も から検出できませんLaunchConfiguration。 Cluster Autoscaler は、 Auto Scaling グループの次のタグからこれらの要因を検出することで、これらの要因を考慮することができます。

Key: k8s.io/cluster-autoscaler/node-template/resources/$RESOURCE_NAME Value: 5 Key: k8s.io/cluster-autoscaler/node-template/label/$LABEL_KEY Value: $LABEL_VALUE Key: k8s.io/cluster-autoscaler/node-template/taint/$TAINT_KEY Value: NoSchedule
注記

ゼロにスケーリングすると、容量は に返Amazon EC2され、今後使用できなくなる可能性があります。

追加の設定パラメータ

Cluster Autoscaler の動作とパフォーマンスを調整するために使用できる多くの設定オプションがあります。パラメータの完全なリストについては、「CA へのパラメータとは」 () を参照してくださいGitHub。

パフォーマンスに関する考慮事項

Cluster Autoscaler のパフォーマンスとスケーラビリティを調整するために変更できる主な項目は、プロセスに提供されるリソース、アルゴリズムのスキャン間隔、クラスター内のノードグループの数です。このアルゴリズムの実際のランタイムの複雑さには、プラグインの複雑さのスケジュールやポッドの数など、他の要因があります。これらは、クラスターのワークロードに自然であり、簡単に調整できないため、設定できないパラメータと見なされます。

スケーラビリティとは、Kubernetes クラスター内のポッドとノードの数が増えるにつれて Cluster Autoscaler がどの程度パフォーマンスを発揮するかを指します。スケーラビリティの制限に達すると、Cluster Autoscaler のパフォーマンスと機能は低下します。さらに、スケーラビリティの制限を超えると、Cluster Autoscaler はクラスター内のノードを追加または削除できなくなります。

パフォーマンスとは、Cluster Autoscaler がスケーリングの決定を迅速に実行および実装できることを意味します。完全に動作する Cluster Autoscaler は、即座に決定を行い、ポッドが切断不能になるなどの刺激に応じてスケーリングアクションを呼び出します。

Auto Scaling アルゴリズムのランタイムの複雑さを理解することで、Cluster Autoscaler を調整して (1,000 ノードを超える) 大規模なクラスターでスムーズに動作し続けることができます。

Cluster Autoscaler は、ポッド、ノード、ノードグループを含め、クラスターの状態全体をメモリにロードします。各スキャン間隔で、アルゴリズムは、分離できないポッドを識別し、各ノードグループのスケジューリングをシミュレートします。これらの要因を調整するには、異なるトレードオフがあり、慎重に検討する必要があります。

垂直自動スケーリング

Cluster Autoscaler を大規模なクラスターにスケーリングする最も簡単な方法は、デプロイのリソースリクエストを増やすことです。メモリと CPU の両方を大規模なクラスターで増やす必要がありますが、これはクラスターサイズによって大きく異なります。Auto Scaling アルゴリズムは、すべてのポッドとノードをメモリに保存します。これにより、メモリのフットプリントが 1 ギガバイトを超えることがあります。リソースの増加は通常、手動で行われます。一定のリソース調整によって運用上の負担が生じていることが判明した場合は、Addon Resizer または Vertical Pod Autoscaler の使用を検討してください。

ノードグループの数を減らす

ノードグループの数を最小限に抑えることは、Cluster Autoscaler が大規模なクラスターで適切に実行されるようにするための 1 つの方法です。これは、ノードグループを個々のチームまたはアプリケーションベースで構成する場合、困難なことがあります。これは Kubernetes API によって完全にサポートされていますが、これはクラスター Autoscaler アンチパターンで、スケーラビリティには影響があると見なされます。スポットや GPU インスタンスなど、複数のノードグループを使用する理由は多数あります。多くの場合、少数のグループを使用して同じ効果を実現する代替設計があります。次の条件が満たされていることを確認します。

  • ポッドの分離は、ノードグループではなく名前空間を使用して行われます。

    • これは、信頼度の低いマルチテナントクラスターでは不可能な場合があります。

    • ポッド ResourceRequestsResourceLimits は、リソースの競合を避けるために適切に設定されます。

    • インスタンスタイプが大きいほど、ビンパッキングの最適化とシステムポッドのオーバーヘッドの削減につながります。

  • NodeTaints または NodeSelectors は、ルールとしてではなく、例外としてポッドをスケジュールするために使用されます。

  • リージョンのリソースは、複数の を持つ単一のAmazon EC2Auto Scalingグループとして定義されますアベイラビリティーゾーン。

スキャン間隔を短くする

10 秒などの低いスキャン間隔は、ポッドが切断不能になったときに Cluster Autoscaler ができるだけ早く応答することを保証します。ただし、スキャンごとに Kubernetes API および Amazon EC2 Auto Scaling グループ、またはAmazon EKSマネージド型ノードグループ への API コールが多数生成されますAPIs。 これらの API コールにより、レート制限が発生したり、Kubernetes コントロールプレーンでサービスが使用できなくなることがあります。

デフォルトのスキャン間隔は 10 秒ですが、 ではAWS、ノードの起動に、新しいインスタンスの起動にかなり時間がかかります。つまり、スケールアップ時間全体を大幅に増やすことなく、間隔を増やすことができます。たとえば、ノードの起動に 2 分かかる場合、間隔を 1 分に変更すると、38% 低速のスケールアップで API コールが 6x 倍減ります。

ノードグループ間のシャーディング

Cluster Autoscaler は、特定のノードグループのセットで動作するように設定できます。この機能を使用すると、Cluster Autoscaler の複数のインスタンスをデプロイできます。各インスタンスは、異なるノードグループのセットで動作するように設定されます。この戦略を使用する場合、任意に多数のノードグループを使用し、拡張性のためのコストを取引できます。ただし、この戦略をパフォーマンスを向上させるための最終手段としてのみ使用することをお勧めします。

Cluster Autoscaler は元々この設定向けに設計されていなかったため、副作用がいくつかあります。シャードは通信しないため、複数の Autoscaler が中断不可能なポッドのスケジュールを試みる可能性があります。これにより、複数のノードグループの不要なスケールアウトが発生する可能性があります。[] の後に追加されるノードはスケールインしますscale-down-delay

metadata: name: cluster-autoscaler namespace: cluster-autoscaler-1 ... --nodes=1:10:k8s-worker-asg-1 --nodes=1:10:k8s-worker-asg-2 --- metadata: name: cluster-autoscaler namespace: cluster-autoscaler-2 ... --nodes=1:10:k8s-worker-asg-3 --nodes=1:10:k8s-worker-asg-4

次の条件が true であることを確認します。

  • 各シャードは、一意のAmazon EC2Auto Scalingグループセットを指すように設定されます。

  • 各シャードは、リーダーの選択競合を回避するために、個別の名前空間にデプロイされます。

コスト効率と可用性

Cluster Autoscaler のコスト効率を調整する主なオプションはAmazon EC2、インスタンスのプロビジョニングに関連しています。また、コスト効率は可用性とのバランスを取る必要があります。このセクションでは、スポットインスタンスを使用してコストを削減し、新しいノードの作成時にレイテンシーを減らすためのオーバープロビジョニングなどの戦略について説明します。

  • 可用性–ポッドは、中断することなくすばやくスケジュールできます。これは、新しく作成されたポッドをスケジュールする必要がある場合や、スケールダウンされたノードがスケジュールされた残りのポッドを終了する場合にも当てはまります。

  • Cost – スケールアウトおよびスケールインイベントの背後にある決定によって決まります。既存のノードが使用率が低すぎる場合や、着信ポッドに対して大きすぎる新しいノードが追加されると、リソースは無駄になります。特定のユースケースによっては、積極的なスケールダウンの決定により、ポッドを途中で終了すると料金が発生する場合があります。

スポットインスタンス

ノードグループでスポットインスタンスを使用すると、オンデマンド料金から最大 90% を節約できます。これにより、 がAmazon EC2容量を必要とするときに、スポットインスタンスが中断される可能性があります。Insufficient Capacity Errors 使用可能な容量がないために Amazon EC2 Auto Scaling グループがスケールアップできないたびに、 が発生します。さまざまなインスタンスファミリーを選択すると、主に 2 つの利点があります。まず、多数のスポットキャパシティープールをタップすることで、希望するスケールを達成する可能性を高めることができます。次に、スポットインスタンスの中断によるクラスターの可用性への影響を減らすこともできます。スポットインスタンスを含む混合インスタンスポリシーは、ノードグループの数を増やすことなく、多様なインスタンスポリシーを増大するのに最適です。ただし、保証されたリソースが必要な場合は、スポットインスタンスの代わりにオンデマンドインスタンスを使用することに注意してください。

スポットインスタンスは、インスタンスの需要が高まったときに終了される場合があります。詳細については、 の「スポットインスタンスの中断」セクションを参照してくださいLinux インスタンス用 Amazon EC2 ユーザーガイド。ノードがダウンすると、AWS ノードのターミネーションハンドラプロジェクトによって Kubernetes コントロールプレーンが自動的にアラートされます。プロジェクトは、Kubernetes API を使用して ノードを認証し、そこに新しい作業がスケジュールされていないことを確認してから、それをドレインして既存の作業を削除します。

混合インスタンスポリシーを設定するときは、すべてのインスタンスタイプで類似したリソース容量が重要です。Autoscaler のスケジュールシミュレーターは、混合インスタンスポリシーの最初のインスタンスタイプを使用します。後続のインスタンスタイプが大きい場合、スケールアップ後にリソースが無駄になることがあります。容量が小さいと、ポッドは容量不足で新しいインスタンスでスケジュールに失敗することがあります。たとえばM4、、、M5および M5a, インスタンスはすべて、CPU とメモリの量が似ておりM5n、混合インスタンスポリシーの優れた候補です。Amazon EC2 Instance Selector ツールは、同様のインスタンスタイプを識別するのに役立ちます。詳細については、「 のAmazon EC2インスタンスセレクタ」を参照してくださいGitHub。

オンデマンドインスタンスとスポットインスタンスの容量を別々のAmazon EC2Auto Scalingグループに分離することをお勧めします。オンデマンドインスタンスとスポットインスタンスのスケジュールプロパティが異なるため、基本容量戦略を使用するよりもこれをお勧めします。スポットインスタンスはいつでも中断できます。が容量を戻すAmazon EC2必要がある場合、プリエンプティブノードが埋め込まれることが多いため、プリエンプション動作に対する明示的なポッドの許容範囲が必要です。これにより、ノードのスケジュールプロパティが異なるため、複数のAmazon EC2Auto Scalingグループに分離する必要があります。

Cluster Autoscaler には、Expanders の概念が含まれています。これらはまとめて、スケーリングするノードグループを選択するためのさまざまな戦略を提供します。戦略--expander=least-wasteは、汎用のデフォルトとして最適です。前述のように、スポットインスタンスの分散に複数のノードグループを使用する場合、スケーリングアクティビティ後に最もよく使用されるグループをスケーリングすることで、ノードグループのコストをさらに最適化できます。

ノードグループまたはグループの優先順位付け Auto Scaling

また、 Priority エクスポータを使用して優先度ベースの自動スケーリングを設定することもできます。--expander=priority により、クラスターはノードグループまたはAuto Scalingグループに優先順位を付けることができます。また、何らかの理由でスケーリングできない場合、優先順位リストで次のノードグループを選択します。これは、GPU がワークロードに最適なパフォーマンスを提供しているため、たとえばP3インスタンスタイプを使用する場合に便利ですが、2 番目のオプションとしてP2インスタンスタイプを使用することもできます。次に例を示します。

apiVersion: v1 kind: ConfigMap metadata: name: cluster-autoscaler-priority-expander namespace: kube-system data: priorities: |- 10: - .*p2-node-group.* 50: - .*p3-node-group.*

Cluster Autoscaler は、名前 に一致するAmazon EC2Auto Scalingグループをスケールアップしようとp2-node-groupします。 このオペレーションが 内で成功しない場合--max-node-provision-time、 という名前の Amazon EC2 Auto Scaling グループをスケーリングしようとしますp3-node-group。 この値はデフォルトで 15 分に設定され、応答性の高いノードグループを選択するために減らすことができますが、値が低すぎると不要なスケールアウトが発生する可能性があります。

Overprovisioning

Cluster Autoscaler は、必要に応じてのみノードを追加し、未使用の場合は削除することで、コストを最小限に抑えます。これにより、多くのポッドがスケジュールできるようになる前にノードのスケールアップを強制的に待機するため、デプロイのレイテンシーに大きく影響します。ノードが使用可能になるまでに数分かかることがあります。これにより、ポッドのスケジュールのレイテンシーが 1 桁増加する可能性があります。

これは、遅延のスケジュールにコストをトレードアップするオーバープロビジョニングを使用して軽減できます。オーバープロビジョニングは、負の優先度の一時ポッドを使用して実装されます。これらのポッドは、クラスター内の領域を占有します。新しく作成されたポッドが中断可能ではなく、優先度が高い場合、一時ポッドはスペースを確保するために取って代わられます。次に、一時ポッドが中断可能になり、Cluster Autoscaler が新しい過剰にプロビジョニングされたノードをスケールアウトします。

オーバープロビジョニングには、他の利点があります。オーバープロビジョニングがないと、使用率の高いクラスター内のポッドは、 preferredDuringSchedulingIgnoredDuringExecution ルールを使用して、最適なスケジューリングの決定を行います。これの一般的なユースケースは、 を使用して アベイラビリティーゾーン間で可用性の高いアプリケーションのポッドを分離することですAntiAffinity。 オーバープロビジョニングは、目的のゾーンのノードが使用可能になる可能性を大幅に増やすことができます。

適切な量の過剰にプロビジョニングされた容量を選択することが重要です。この決定を行う 1 つの方法は、平均スケールアップ頻度を決定し、この数を新しいノードのスケールアップにかかる時間で割ります。たとえば、平均して新しいノードが 30 秒ごとに必要になり、新しいノードのプロビジョニングに 30 秒Amazon EC2かかる場合、オーバープロビジョニングの単一ノードにより、常に利用可能な追加のノードがあることが保証されます。これにより、1 つの追加のAmazon EC2インスタンスのコストで、スケジュールのレイテンシーを 30 秒短縮できます。ゾーンに基づくスケジューリングの決定を改善するには、Amazon EC2Auto Scalingグループ内のアベイラビリティーゾーンの数と等しいノード数を過剰にプロビジョニングできます。これにより、スケジューラは着信ポッドに最適なゾーンを選択できます。

スケールダウンの削除の防止

一部のワークロードは削除コストが高くなります。ビッグデータ分析、機械学習タスク、およびテストランナーは完了までに長時間かかる場合があり、中断された場合は再起動する必要があります。Cluster Autoscaler は、 の下の任意のノードをスケールダウンする機能を実行しますscale-down-utilization-threshold。 これにより、ノードの残りのポッドが中断されます。ただし、これを防ぐには、削除にコストがかかるポッドが、Cluster Autoscaler によって認識されるラベルで保護されるようにします。これを行うには、削除にコストがかかるポッドにラベル があることを確認しますcluster-autoscaler.kubernetes.io/safe-to-evict=false