このトピックでは、ノードの自動スケーリング機能を使用する際に発生する可能性のある一般的な問題と解決策について説明します。
目次
カテゴリ | サブカテゴリ | リンク |
ノードの自動スケーリングのスケーリング動作 | ||
cluster-autoscaler は CustomResourceDefinitions (CRD) をサポートしていますか? | ||
カスタムスケーリング動作 | ||
cluster-autoscaler アドオン関連 | ||
既知の制限事項
利用可能なノードリソースを完全に予測できない
新しくプロビジョニングされたノードで利用可能なリソースは、インスタンスタイプの仕様と正確に一致しない場合があります。これは、Elastic Compute Service (ECS) インスタンス上の基盤となる OS とシステムデーモンがリソースを消費するためです。詳細については、「インスタンスを購入した後、メモリサイズがインスタンスタイプの仕様と異なるのはなぜですか?」をご参照ください。
このオーバーヘッドのため、cluster-autoscaler が使用するリソースの見積もりは、新しいノードで実際に割り当て可能なリソースよりもわずかに高くなる可能性があります。この差異は通常小さいですが、Pod のリソースリクエストを設定する際には、以下の点に注意することが重要です:
インスタンスの全容量よりも少ないリクエスト:CPU、メモリ、ディスクを含む合計リクエストリソースは、インスタンスタイプの仕様よりも少なくなければなりません。一般的なガイドラインとして、Pod の合計リソースリクエストがノード容量の 70% を超えないようにすることを推奨します。
Kubernetes 以外の Pod や静的 Pod を考慮に入れる:ノードに十分なリソースがあるかどうかを判断する際、cluster-autoscaler は Kubernetes Pod (保留中の Pod や DaemonSet Pod を含む) のリソースリクエストのみを考慮します。DaemonSet として管理されていない静的 Pod を実行する場合は、手動でそれらのリソースを考慮し、予約する必要があります。
大規模な Pod を事前にテストする:Pod が大量のリソース (例えば、ノードリソースの 70% 以上) をリクエストする場合、事前に同じインスタンスタイプのノードに Pod をスケジュールできることをテストし、確認する必要があります。
限定的なスケジューリングポリシー
cluster-autoscaler アドオンは、スケジュール不可能な Pod が Auto Scaling が有効なノードプールにスケジュールできるかどうかを判断するために、限られたスケジューリングポリシーセットのみをサポートします。詳細については、「cluster-autoscaler は、どのスケジューリングポリシーを使用して、スケジュール不可能な Pod が自動スケーリングが有効なノードプールにスケジュールできるかどうかを判断しますか?」をご参照ください。
resource タイプのポリシーのみをサポート
ResourcePolicy を使用してエラスティックリソースの優先度をカスタマイズする場合、resource タイプのポリシーのみがサポートされます。詳細については、「エラスティックリソースのスケジューリング優先度のカスタマイズ」をご参照ください。
apiVersion: scheduling.alibabacloud.com/v1alpha1
kind: ResourcePolicy
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
units:
- resource: ecs
- resource: eci複数タイプを持つノードプールで特定のインスタンスタイプをスケールアウトすることはサポートされていません
ノードプールが複数のインスタンスタイプで構成されている場合、スケールアウト操作中に cluster-autoscaler に特定のインスタンスタイプをプロビジョニングするように指示することはできません。
代わりに、cluster-autoscaler は、利用可能な最小のインスタンスタイプ (つまり、CPU やメモリなどのリソースが最も少ないインスタンスタイプ) に基づいて、ノードプール全体の容量をモデル化します。この計算の詳細については、「スケーリンググループに複数のインスタンスタイプが設定されている場合、オートスケーラーはどのようにグループの容量を計算してスケーリングを決定しますか?」をご参照ください。
ゾーン固有の制約を持つ Pod は、マルチゾーンのノードプールでスケールアウトをトリガーできない場合があります
ノードプールが複数のアベイラビリティゾーンにまたがっている場合、特定のゾーンに依存する Pod はスケールアウトをトリガーしない可能性があります。これは、Pod が以下の理由で特定のゾーンを必要とする場合に発生する可能性があります:
その特定のゾーンにあるボリュームにバインドされた永続ボリューム要求 (PVC)。
ゾーンをターゲットとする
nodeSelector、nodeAffinity、またはその他のスケジューリングルール。
これらの場合、cluster-autoscaler は、必要なアベイラビリティゾーンに新しいノードをプロビジョニングできない可能性があります。このようなケースの詳細については、「ノードの自動スケーリングアドオンがノードの作成に失敗するのはなぜですか?」をご参照ください。
ストレージの制約
オートスケーラーは、Pod が持つ可能性のある特定のストレージ制約を認識しません。これには、次のような要件が含まれます:
永続ボリューム (PV) にアクセスするために、特定のアベイラビリティゾーンで実行する必要がある。
特定のディスクタイプ (ESSD など) をサポートするノードが必要である。
解決策:専用のノードプールを設定する
アプリケーションにこのようなストレージ依存関係がある場合は、そのプールで Auto Scaling を有効にする前に、専用のノードプールを設定してください。
ノードプールの構成でアベイラビリティゾーン、インスタンスタイプ、ディスクタイプを事前に設定することで、新しくプロビジョニングされるノードが Pod のストレージマウント要件を満たすことを保証します。これにより、リソースの不一致によるスケジューリングの失敗や Pod の起動エラーを防ぐことができます。
さらに、Pod が Terminating 状態のままになっている PVC を参照していないことを確認してください。PVC が終了中のためにスケジュールできない Pod は、継続的にスケジューリングに失敗します。これにより、cluster-autoscaler が誤ったスケーリング判断 (Pod のエビクション試行やクラスターの不必要なスケーリングなど) を下す可能性があります。
スケールアウトの動作
どのようなスケジューリングポリシーをcluster-autoscalerは、スケジュール不可能な Pod が自動スケーリングが有効なノードプールにスケジュール可能かどうかを判断するのに使用しますか?
cluster-autoscaler は、以下のスケジューリングポリシーを使用してこの判断を行います:
PodFitsResources
GeneralPredicates
PodToleratesNodeTaints
MaxGCEPDVolumeCount
NoDiskConflict
CheckNodeCondition
CheckNodeDiskPressure
CheckNodeMemoryPressure
CheckNodePIDPressure
CheckVolumeBinding
MaxAzureDiskVolumeCount
MaxEBSVolumeCount
ready
NoVolumeZoneConflict
どのリソースを cluster-autoscaler はスケジューリング分析中にシミュレートできますか?
cluster-autoscaler は、以下のリソースタイプのシミュレーションと評価をサポートしています:
cpu
memory
sigma/eni
ephemeral-storage
aliyun.com/gpu-mem (shared GPUs only)
nvidia.com/gpu他のリソースタイプに基づいてスケーリングする必要がある場合は、「Auto Scaling が有効になっているノードプールにカスタムリソースを設定するにはどうすればよいですか?」をご参照ください。
ノードの自動スケーリングアドオンがノードの作成に失敗するのはなぜですか?
この問題は、いくつかの一般的なシナリオによって引き起こされる可能性があります。問題を診断するために、以下の可能性を確認してください:
ノードプールに Auto Scaling が設定されていない
ノードの自動スケーリングは、Auto Scaling が設定されたノードプールでのみ機能します。クラスターレベルの自動スケーリング機能が有効になっており、ノードプールのスケーリングモードが [自動] に設定されていることを確認してください。詳細については、「ノードの自動スケーリングの有効化」をご参照ください。
Pod のリソースリクエストが利用可能なインスタンスタイプの割り当て可能容量を超えている
スケーリンググループ内のインスタンスタイプが Pod のリソースリクエストを満たせません。ECS インスタンスの公表されている仕様は、その総容量を表します。しかし、これらのリソースの一部は、OS カーネル、システムサービス、および必須の Kubernetes デーモン (kubelet、kube-proxy、Terway、コンテナランタイムなど) の安定した動作を保証するために、常に ACK によって予約されています。
この予約により、ノードの総容量と、Pod で実際に利用可能な CPU、メモリ、ストレージの量である割り当て可能リソースとの間に重大な差異が生じます。
標準の cluster-autoscaler は、Kubernetes バージョン 1.28 以前のリソース予約ポリシーを使用してスケーリングを決定します。
新しい Kubernetes バージョンのより正確な予約ポリシーを使用するには、新しいアルゴリズムが組み込まれているノードの高速スケーリングに切り替えることを推奨します。または、ノードプールの構成でカスタムリソース予約を手動で定義することもできます。
システムによって消費されるリソースの詳細については、「購入したインスタンスのメモリサイズがインスタンスタイプで定義されたメモリサイズと異なるのはなぜですか?」をご参照ください。
アドオンによって消費されるリソースの詳細については、「ノードリソース予約ポリシー」をご参照ください。
デフォルトでは、システムアドオンはノードにインストールされます。Pod によってリクエストされるリソースは、インスタンスの仕様よりも少なくなければなりません。
Pod のゾーン固有の制約がスケールアウトを妨げている
Pod が特定のアベイラビリティゾーンにスケジューリング上の依存関係 (ゾーンボリュームにバインドされた PVC やノードアフィニティルールなど) を持っている場合、特にマルチゾーンのノードプール内では、cluster-autoscaler がその特定のゾーンに新しいノードをプロビジョニングできない可能性があります。
必要な権限が付与されていない
cluster-autoscaler は、クラスターリソースを管理するために特定の権限を必要とします。これらの権限はクラスター全体に適用され、クラスターごとに付与される必要があります。
「クラスターのノード自動スケーリングを有効にする」で説明されているすべての権限付与手順を完了していることを確認してください。
異常なノードが原因でオートスケーラーが一時的に停止している
オートスケーラーには、繰り返しの失敗を防ぐための安全機構 (ダンピング) が含まれています。プロビジョニングしたノードがその後クラスターへの参加に失敗したり、長期間
NotReady状態のままであったりすると、さらなるスケーリング操作を一時的に停止します。異常なノードの問題を解決してください。状態が解消されると、スケーリングは自動的に再開されます。
クラスターにワーカーノードが存在しない
cluster-autoscaler 自体はクラスター内の Pod として実行されます。ワーカーノードがない場合、オートスケーラー Pod は実行できず、したがって新しいノードをプロビジョニングすることもできません。
コアクラスターアドオンの高可用性を確保するために、ノードプールを最低 2 つのノードで構成してください。ユースケースでゼロからのスケールアウトまたはゼロへのスケールダウンが必要な場合は、ノードの高速スケーリング機能を使用してください。
スケーリンググループに複数のインスタンスタイプが設定されている場合、オートスケーラーはどのようにグループの容量を計算してスケーリングを決定しますか?
複数のインスタンスタイプで構成されたスケーリンググループの場合、cluster-autoscaler は、構成されているすべてのインスタンスタイプの中から、各リソースディメンション (CPU やメモリなど) の最小値に基づいてグループ全体の容量をモデル化します。
たとえば、2 つのインスタンスタイプで構成されたスケーリンググループを考えてみましょう:
インスタンスタイプ A:4 vCPU、32 GiB メモリ
インスタンスタイプ B:8 vCPU、16 GiB メモリ
このグループのベースラインを決定するために、オートスケーラーは各リソースの最小値を計算します:
最小 CPU:min(4, 8) = 4 vCPU
最小メモリ:min(32, 16) = 16 GiB
その結果、オートスケーラーはこのスケーリンググループ全体を、4 vCPU と 16 GiB のメモリを持つノードしかプロビジョニングできないかのように扱います。
したがって、保留中の Pod が 4 vCPU または 16 GiB のメモリを超えるリソースをリクエストした場合、インスタンスタイプの 1 つ (8 vCPU, 16 GiB) が理論的に CPU リクエストを満たすことができたとしても、オートスケーラーはこのグループのスケールアウトをトリガーしません。
複数のインスタンスタイプ構成を使用し、かつリソース予約も考慮する必要がある場合は、「ノードの自動スケーリングアドオンがノードの作成に失敗するのはなぜですか?」をご参照ください。
Auto Scaling が有効になっているノードプールが複数ある場合、cluster-autoscaler はどれをスケールアウト対象として選択しますか?
Pod がスケジュール不可能な場合、cluster-autoscaler はシミュレーションを実行して、自動スケーリングされたノードプールのうち、どれが Pod を収容できるかを判断します。このシミュレーションは、各ノードプールをその構成 (ラベル、Taint、利用可能なインスタンスタイプなど) に基づいて評価します。
シミュレーションによって、そのプールからの新しいノードが Pod のスケジューリングを可能にすることが示された場合、そのノードプールはスケールアウトの候補と見なされます。
この条件を満たすノードプールが複数ある場合、ノードの自動スケーリングはデフォルトで最も無駄の少ない拡張戦略を使用します。この戦略は、新しい Pod がスケジュールされた後に残る未使用リソース (CPU とメモリ) の量が最も少なくなるノードプールを選択します。
Auto Scaling が有効になっているノードプールにカスタムリソースを設定するにはどうすればよいですか?
Auto Scaling が有効になっているノードプールに、特定のプレフィックスを持つ ECS タグを設定します。これにより、cluster-autoscaler はノードプールで利用可能なカスタムリソースや、指定されたリソースの正確な値を識別できます。
k8s.io/cluster-autoscaler/node-template/resource/{resource_name}:{resource_size}例:
k8s.io/cluster-autoscaler/node-template/resource/hugepages-1Gi:2Giノードプールで Auto Scaling を有効にできないのはなぜですか?
ノードプールで Auto Scaling を有効にできない場合、以下のいずれかの理由が考えられます:
デフォルトのノードプールである
ノードの自動スケーリング機能は、クラスターのデフォルトのノードプールでは有効にできません。
ノードプールに手動で追加されたノードが含まれている
手動で追加されたノードが既にあるノードプールでは、Auto Scaling を有効にできません。これを解決するには、まず手動で追加されたノードを削除するか、または、最初から Auto Scaling を有効にした新しい専用のノードプールを作成することを推奨します。
ノードプールにサブスクリプションベースのインスタンスが含まれている
ノードの自動スケーリング機能は、サブスクリプションベースで課金されるノードをサポートしていません。従量課金インスタンスとのみ互換性があります。
スケールインの動作
なぜ cluster-autoscaler はノードのスケールインに失敗するのですか?
cluster-autoscaler がノードのスケールインを妨げられる理由はいくつかあります。以下のいずれかのケースが当てはまるか確認してください:
ノードの Pod が使用率のしきい値を超えている
ノード上で実行されている Pod の合計リソースリクエストが、設定されたスケールインのしきい値よりも高い場合、そのノードはスケールインの対象とは見なされません。
ノードが
kube-systemPod を実行しているデフォルトでは、cluster-autoscaler は
kube-system名前空間の Pod を実行しているノードを削除しません。Pod に制限の厳しいスケジューリング制約がある
ノードが、クラスター内の他の利用可能なノードへの再スケジュールを妨げる厳格なスケジューリング制約 (
nodeSelectorや強力なnodeAffinityなど) を持つ Pod を実行している場合、そのノードはスケールインできません。Pod が PodDisruptionBudget (PDB) によって保護されている
ノードが PDB によって保護されているワークロードの一部である Pod を実行しており、その Pod をエビクションすることが PDB の
minAvailableまたはmaxUnavailable設定に違反する場合、そのノードはスケールダウンできません。
その他のよくある質問と回答については、「cluster-autoscaler」をご参照ください。
特定の DaemonSet のエビクションを有効または無効にするにはどうすればよいですか?
cluster-autoscaler は、[DaemonSet Pod のエビクション] 構成に基づいて DaemonSet Pod をエビクションするかどうかを決定します。この構成はクラスター全体に適用され、クラスター内のすべての DaemonSet Pod に適用されます。詳細については、「ステップ 1:クラスターのノード自動スケーリングを有効にする」をご参照ください。
ただし、Pod にアノテーションを追加することで、DaemonSet ごとにこのグローバル設定を上書きできます。
特定の DaemonSet の Pod のエビクションを明示的に有効にするには、次のアノテーションを追加します:
"cluster-autoscaler.kubernetes.io/enable-ds-eviction":"true"特定の DaemonSet の Pod のエビクションを明示的に無効にするには、次のアノテーションを追加します:
"cluster-autoscaler.kubernetes.io/enable-ds-eviction":"false"
[DaemonSet Pod のエビクション] が無効の場合、
enable-ds-eviction: "true"アノテーションは 空ではないノード 上のDaemonSetPod に対してのみ有効になります。空のノードからDaemonSetPod のエビクションを有効にするには、まずグローバルな DaemonSet のエビクション設定を有効にする必要があります。これらのアノテーションは、
DaemonSetオブジェクト自体ではなく、DaemonSetPod 自体に適用する必要があります (通常はDaemonSetマニフェストの Pod テンプレートに追加します)。これらのアノテーションは、
DaemonSetの一部ではない Pod には効果がありません。デフォルトでは、cluster-autoscaler は
DaemonSetPod を非ブロッキング方式でエビクションします。これは、DaemonSetPod のエビクションが完了するのを待たずに次のステップに進むことを意味します。cluster-autoscaler がスケールインを続行する前に、特定のDaemonSetPod が完全にエビクションされるのを待つ必要がある場合は、enable-ds-evictionアノテーションに加えて、"cluster-autoscaler.kubernetes.io/wait-until-evicted": "true"アノテーションを Pod に追加します。
どのような種類の Pod が cluster-autoscaler によるノードの削除を妨げる可能性がありますか?
cluster-autoscaler は、ネイティブの Kubernetes コントローラー (Deployment、ReplicaSet、Job、StatefulSet など) によって作成されていない Pod が含まれている場合、またはノード上の Pod を安全に終了または移行できない場合に、ノードの削除をブロックされる可能性があります。
ノードのスケールインをブロックする可能性のあるすべての条件の包括的なリストについては、「どのような種類の Pod が CA によるノードの削除を妨げる可能性がありますか?」をご参照ください。
拡張機能のサポート
cluster-autoscaler の、カスタムリソース定義 (CRD) に対するサポートはありますか?
いいえ、cluster-autoscaler は現在、標準の Kubernetes オブジェクトのみをサポートしており、Kubernetes CRD はサポートしていません。
Pod 単位のスケーリング動作制御
特定の Pod のスケールアウト遅延を設定するにはどうすればよいですか?
この動作は、Pod に cluster-autoscaler.kubernetes.io/pod-scale-up-delay アノテーションを追加することで制御できます。
cluster-autoscaler は、この遅延期間が経過しても Pod がスケジュール不可能なままである場合にのみ、スケールアウトの対象として Pod を考慮します。これにより、スケールアップがトリガーされる前に、ネイティブの Kubernetes スケジューラが既存のノードに Pod を配置しようとするための追加の時間が与えられます。
アノテーションの例:"cluster-autoscaler.kubernetes.io/pod-scale-up-delay": "600s"。
Pod アノテーションを使用して cluster-autoscaler のスケールイン動作を制御するにはどうすればよいですか?
Pod アノテーション cluster-autoscaler.kubernetes.io/safe-to-evict を使用して、cluster-autoscaler に特定の Pod がノードのスケールインを許可するために安全にエビクションできるかどうかを明示的に伝えます。
ノードがスケールインされるのを防ぐには、ノード上で実行されている Pod にアノテーション
"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"を追加します。この Pod の存在が、オートスケーラーによるノードの終了をブロックします。ノードがスケールインされるのを許可するには、Pod にアノテーション
"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"を追加します。これにより、スケールイン操作中に Pod がエビクションしても安全であることが明示的にマークされます。
ノード単位のスケーリング動作制御
特定のノードが cluster-autoscaler によってスケールインされないようにするには、どうすればよいですか?
対象のノードが cluster-autoscaler によってスケールインされるのを防ぐには、そのノードにアノテーション "cluster-autoscaler.kubernetes.io/scale-down-disabled": "true" を追加します。
このアノテーションを追加するには、次の kubectl コマンドを実行し、<nodename> を対象のノード名に置き換えます:
kubectl annotate node <nodename> cluster-autoscaler.kubernetes.io/scale-down-disabled=truecluster-autoscaler アドオン関連
どうすれば cluster-autoscaler を最新バージョンにアップグレードできますか?
Auto Scaling が有効になっているクラスターの場合、次のように cluster-autoscaler をアップグレードします:
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
クラスター ページで、管理対象のクラスターを見つけてその名前をクリックします。左側のナビゲーションウィンドウで、 を選択します。
[ノードのスケーリング] の右側にある [編集] をクリックします。表示されるパネルで [OK] をクリックして、アドオンを最新バージョンにアップグレードします。
どのような操作が cluster-autoscaler の自動更新をトリガーしますか?
cluster-autoscaler の構成が最新であり、そのバージョンがクラスターと互換性があることを保証するために、以下の操作が自動更新または調整をトリガーします:
自動スケーリング構成の変更。
Auto Scaling が有効になっているノードプールの作成、削除、または更新。
クラスターの Kubernetes バージョンのアップグレード成功。
必要なロール権限が付与されているにもかかわらず、ACK マネージドクラスター で ノードのスケーリング が機能しないのはなぜですか?
考えられる原因
この問題は、kube-system 名前空間内の Secret から必要なトークン (addon.aliyuncsmanagedautoscalerrole.token) が欠落している場合に発生する可能性があります。デフォルトでは、ACK はクラスターの Worker Role を使用して自動スケーリング機能を有効にし、このトークンはそれらの操作を認証するために不可欠です。
解決策
解決策は、ACK コンソールの権限付与ウィザードを使用して、クラスターの Worker Role に必要なポリシーを再適用することです。
クラスター ページで、管理対象のクラスターを見つけてその名前をクリックします。左側のナビゲーションウィンドウで、 を選択します。
[ノードプール] ページで、[ノードのスケーリング] の右側にある [有効化] をクリックします。
画面の指示に従って
KubernetesWorkerRoleを承認し、AliyunCSManagedAutoScalerRolePolicyシステムポリシーをアタッチします。
権限をすぐに有効にするには、
kube-system名前空間で、cluster-autoscalerDeployment(ノードの自動スケーリング)またはack-goatscalerDeployment(ノードの即時スケーリング)を手動で再起動します。