次の方法で共有


Azure Kubernetes Service (AKS) でノード自動プロビジョニング (NAP) ノードのノード中断ポリシーを構成する

この記事では、Azure Kubernetes Service (AKS) ノード自動プロビジョニング (NAP) ノードのノード中断ポリシーを構成する方法と、リソース使用率とコスト効率を最適化するための中断のしくみについて説明します。

NAP では、次の方法でクラスターが最適化されます。

  • 使用率の低いノードの削除または置換。
  • ワークロードを統合してコストを削減する。
  • 中断の予算とメンテナンス期間を尊重する。
  • 必要に応じて手動制御を提供します。

開始する前に

NAP ノードのノード中断のしくみ

Karpenter は、各ノードに Kubernetes ファイナライザー を設定し、プロビジョニングするノード要求を行います。 ファイナライザーはノードオブジェクトの削除をブロックしますが、終了コントローラーは、基になるノード要求を削除する前にノードに汚点をつけて排出します。

ノード上のワークロードがスケールダウンされると、NAP はノード プール仕様の中断ルールを使用して、それらのノードを削除するタイミングと方法を決定し、ワークロードのスケジュールを変更して効率を高めます。

ノード中断方法

NAP は中断の対象となるノードを自動的に検出し、必要に応じ交換を開始します。 有効期限統合ドリフト、手動メソッド、外部システムなどの自動化された方法を使用して中断をトリガーできます。

有効期限

有効期限を使用すると、NAP ノードの最大有効期間を設定できます。 ノードは、ノード プールの spec.disruption.expireAfter 値に指定した期間に達すると、期限切れとしてマークされ、中断されます。

有効期限の構成の例

次の例は、NAP ノードの有効期限を 24 時間に設定する方法を示しています。

spec:
  disruption:
    expireAfter: 24h  # Expire nodes after 24 hours

Consolidation

NAP は、ノードが空であるか使用率が低いためにノードを削除できるか、またはノードを低価格のバリアントに置き換えることができるかを特定することで、クラスター コストを積極的に削減するために機能します。 このプロセスは 統合と呼ばれます。 NAP では、主に統合を使用してノードを削除または置換し、ポッドの配置を最適化します。

NAP では、リソース使用率を最適化するために、次の種類の統合が実行されます。

  • 空のノード統合: 空のノードを並列で削除します。
  • マルチノード統合: 複数のノードを削除し、1 つの置換を開始する可能性があります。
  • 単一ノード統合: 単一ノードを削除し、置換を開始する可能性があります。

spec.disruption.consolidationPolicyまたはWhenEmpty設定を使用して、ノード プール仕様のWhenEmptyOrUnderUtilized フィールドを使用して統合をトリガーできます。 また、 consolidateAfter フィールドを設定することもできます。これは、ノードを中断する前に統合機会を検出した後に NAP が待機する時間を決定する時間ベースの条件です。

統合構成の例

次の例は、ノードが空のときにノードを統合し、統合の機会を検出してからノードを中断するまで 30 秒間待機するように NAP を構成する方法を示しています。

  disruption:
    # Describes which types of nodes NAP should consider for consolidation
    # `WhenEmptyOrUnderUtilized`: NAP considers all nodes for consolidation and attempts to remove or replace nodes when it discovers that the node is empty or underutilized and could be changed to reduce cost
    # `WhenEmpty`: NAP only considers nodes for consolidation that don't contain any workload pods
    
    consolidationPolicy: WhenEmpty

    # The amount of time NAP should wait after discovering a consolidation decision
    # Currently, you can only set this value when the consolidation policy is `WhenEmpty`
    # You can choose to disable consolidation entirely by setting the string value `Never`
    consolidateAfter: 30s

Drift

Drift は、 NodePool/AKSNodeClass リソースへの変更を処理します。 NodeClaimTemplateSpec / AKSNodeClassSpecの値は、設定されているのと同じ方法で反映されます。 NodeClaim で関連付けられているNodePool/AKSNodeClassの値がの値と一致しない場合、NodeClaimドリフトとして検出されます。 ポッドへのアップストリームの deployment.spec.template 関係と同様に、Karpenter は関連付けられている NodePool/AKSNodeClassNodeClaimTemplateSpec のハッシュを使用して注釈を付けてドリフトを確認します。 Karpenter は、次のシナリオで Drifted 状態条件を削除します。

  • Driftフィーチャ ゲートは有効になっていませんが、NodeClaimはドリフトしている状態です。
  • NodeClaim はドリフトしていませんが、状態状態を持っています。

Karpenter またはクラウド プロバイダー インターフェイスは、NodeClaim/Instance/NodePool/の変更によってトリガーされるAKSNodeClassを検出する場合があります。

ドリフト時の特殊なケース

特殊なケースでは、誤差は複数の値に対応する可能性があり、異なる方法で処理する必要があります。 解決済みフィールドの誤差により、カスタム リソース定義 (CRD) に変更を加えずにドリフトが発生したり、CRD の変更によって誤差が生じなかったりする場合があります。

たとえば、 NodeClaimnode.kubernetes.io/instance-type: Standard_D2s_v3があり、要件が node.kubernetes.io/instance-type In [Standard_D2s_v3] から node.kubernetes.io/instance-type In [Standard_D2s_v3, Standard_D4s_v3]に変更された場合、その値は新しい要件と互換性があるため、 NodeClaim はドリフトしません。 逆に、 NodeClaimNodeClaimimageFamilyを使用しているが、 spec.imageFamily フィールドが変化した場合、Karpenter は NodeClaimドリフト として検出し、その仕様を満たすようにノードを回転させます。

Important

Karpenter は、サブネット構成の変更を監視し、vnetSubnetIDAKSNodeClassが変更されたときの誤差を検出します。 この動作を理解することは、カスタム ネットワーク構成を管理する際に重要です。 詳細については、「 サブネットのドリフト動作」を参照してください。

詳細については、「 ドリフト設計」を参照してください。

終了猶予期間

ノード プール仕様の spec.template.spec.terminationGracePeriod フィールドを使用して、NAP ノードの終了猶予期間を設定できます。 この設定を使用すると、ポッドが正常に終了するまで Karpenter が待機する時間を構成できます。 この設定はポッドの terminationGracePeriodSeconds よりも優先され、 PodDisruptionBudgetskarpenter.sh/do-not-disrupt 注釈がバイパスされます。

終了猶予期間の構成の例

次の例は、NAP ノードの終了猶予期間を 30 秒に設定する方法を示しています。

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      terminationGracePeriod: 30s

中断予算

ノード プール仕様の spec.disruption.budgets フィールドを変更することで、Karpenter の中断をレート制限できます。 この設定を未定義のままにすると、Karpenter は既定で nodes: 10% を持つ 1 つの予算に設定されます。 予算は、あらゆる理由で削除されるノードを考慮し、有効期限、ドリフト、空さ、合併によって発生する Karpenter の自発的な中断のみを阻止します。

予算によってノードの中断がブロックされるかどうかを計算する場合、Karpenter はノード プールによって所有されているノードの合計数をカウントし、削除されるノードと NotReadyされているノードを減算します。 予算が 20%などのパーセンテージ値で構成されている場合、Karpenter は許可された中断の数を allowed_disruptions = roundup(total * percentage) - total_deleting - total_notreadyとして計算します。 ノード プール内の複数の予算の場合、Karpenter は各予算の最小値 (最も制限が厳しい) 値を受け取ります。

スケジュールフィールドと期間フィールド

予算を使用する場合は、必要に応じて schedule フィールドと duration フィールドを設定して、時間ベースの予算を作成できます。 これらのフィールドを使用すると、中断の制限がより厳しい場合に、メンテナンス期間または特定の期間を定義できます。

  • スケジュール では、 @yearly@monthly@weekly@daily@hourlyなどの特殊なマクロを含む cron ジョブ構文が使用されます。
  • 期間 を使用すると、 10h5m30m160hなどの複合期間を使用できます。 期間とスケジュールを一緒に定義する必要があります。

スケジュールと期間の例

メンテナンス期間の予算

営業時間中の中断を防ぐ:

budgets:
- nodes: "0"
  schedule: "0 9 * * 1-5"  # 9 AM Monday-Friday
  duration: 8h             # For 8 hours
週末のみの中断

週末にのみ中断を許可します。

budgets:
- nodes: "50%"
  schedule: "0 0 * * 6"    # Saturday midnight
  duration: 48h            # All weekend
- nodes: "0"               # Block all other times
段階的な導入予算

中断率の増加を許可します。

budgets:
- nodes: "1"
  schedule: "0 2 * * *"    # 2 AM daily
  duration: 2h
- nodes: "3"
  schedule: "0 4 * * *"    # 4 AM daily
  duration: 4h

予算構成の例

次の NodePool 仕様では、3 つの予算が構成されています。

  • 最初の予算では、ノード プールが所有するノードの 20% を一度に中断できます。
  • 2 番目の予算は上限として機能し、25 を超えるノードがある場合にのみ 5 つの中断を許可します。
  • 最後の予算は、毎日の最初の 10 分間の中断をブロックします。
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    expireAfter: 720h # 30 * 24h = 720h
    budgets:
    - nodes: "20%"      # Allow 20% of nodes to be disrupted
    - nodes: "5"        # Cap at maximum 5 nodes
    - nodes: "0"        # Block all disruptions during maintenance window
      schedule: "@daily" # Scheduled daily
      duration: 10m # Duration of 10 minutes

ノードの手動中断

kubectlを使用するか、NodePoolリソースを削除することで、NAP ノードを手動で中断できます。

kubectl を使用してノードを削除する

kubectl delete node コマンドを使用して、ノードを手動で削除できます。 ラベルを使用して、特定のノード、すべての NAP マネージド ノード、またはノードを特定のノード プールから削除できます。次に例を示します。

# Delete a specific node
kubectl delete node $NODE_NAME

# Delete all NAP-managed nodes
kubectl delete nodes -l karpenter.sh/nodepool

# Delete nodes from a specific nodepool
kubectl delete nodes -l karpenter.sh/nodepool=$NODEPOOL_NAME

NodePool リソースを削除する

NodePoolは、所有者参照を通じてNodeClaimsを所有します。 関連付けられている NodePoolを削除すると、NAP は連鎖削除によってノードを正常に終了します。

注釈を使用して中断を制御する

注釈を使用して、特定のポッド、ノード、またはノード プール全体の中断をブロックまたは無効にすることができます。

ポッド コントロール

karpenter.sh/do-not-disrupt: "true"注釈を設定して、NAP が特定のポッドを中断しないようにブロックします。

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

この注釈は、有効期限、統合、およびドリフトに対する自発的な中断を防止します。 ただし、外部システムからの中断や、 kubectl または NodePool 削除による手動の中断を防ぐことはありません。

ノード コントロール

NAP が特定のノードを中断しないようにブロックします。

apiVersion: v1
kind: Node
metadata:
  annotations:
    karpenter.sh/do-not-disrupt: "true"

ノードプールの管理

NodePool内のすべてのノードの中断を無効にします。

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

次のステップ

AKS でのノード自動プロビジョニングの詳細については、次の記事を参照してください。