Azure Kubernetes Service (AKS) クラスターに Azure スポット ノード プールを追加する

スポット ノード プールは、Azure スポット仮想マシン スケール セットによってサポートされるノード プールです。 AKS クラスターのノードにスポット VM を使用すると、Azure の未使用の容量を利用できるため、コストが大幅に削減されます。 使用可能な未使用の容量は、ノード サイズ、リージョン、時刻などの多くの要因によって異なります。

スポット ノード プールをデプロイすると、使用可能な容量が存在する場合、Azure ではスポット ノードが割り当てられます。 スポット ノードの SLA は存在しません。 スポット ノード プールをサポートするスポット スケール セットは 1 つの障害ドメインにデプロイされ、高可用性の保証は提供されません。 Azure で容量を元に戻すことが必要になると、Azure インフラストラクチャではいつでもスポット VM が削除されます。

スポット ノードは、中断、早期終了、または排除を処理できるワークロードに最適です。 たとえば、バッチ処理ジョブ、開発、テスト環境などのワークロード、サイズの大きな計算ワークロードを、スポット ノード プールに対してスケジュールしてみるといいかもしれません。

この記事では、既存の Azure Kubernetes Service (AKS) クラスターにセカンダリ スポット ノード プールを追加します。

この記事は、Kubernetes および Azure Load Balancer の基本的な概念を理解していることを前提としています。 詳細については、「Azure Kubernetes Services (AKS) における Kubernetes の中心概念」を参照してください。

Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。

開始する前に

スポット ノード プールを使用するクラスターを作成する場合は、そのクラスターで、ノード プールと Standard SKU ロード バランサーに仮想マシン スケール セットを使用する必要があります。 また、クラスターの作成後に別のノード プールを追加する必要もあります。これについては後の手順で説明します。

この記事では、Azure CLI バージョン 2.14 以降を実行している必要があります。 バージョンを確認するには、az --version を実行します。 インストールまたはアップグレードする必要がある場合は、Azure CLI のインストールに関するページを参照してください。

制限事項

スポット ノード プールを含む AKS クラスターを作成および管理する場合は、次の制限が適用されます。

  • スポット ノード プールをクラスターの既定のノード プールにすることはできません。 スポット ノード プールはセカンダリ プールとしてのみ使用できます。
  • コントロール プレーンとノード プールを一度にアップグレードすることはできません。 個別にアップグレードするか、またはスポット ノード プールを削除して、コントロール プレーンと残りのノード プールを一度にアップグレードする必要があります。
  • スポット ノード プールでは、仮想マシン スケール セットを使用する必要があります。
  • 作成後に ScaleSetPriority または SpotMaxPrice を変更することはできません。
  • SpotMaxPrice を設定するときは、この値を -1 か、または小数点以下最大 5 桁の正の値にする必要があります。
  • スポット ノード プールにはラベル kubernetes.azure.com/scalesetpriority:spot、taint kubernetes.azure.com/scalesetpriority=spot:NoSchedule が割り当てられ、システム ポッドにはアンチアフィニティが割り当てられます。
  • スポット ノード プールでワークロードをスケジュールするには、対応する toleration とアフィニティを追加する必要があります。

AKS クラスターにスポット ノード プールを追加する

複数のノード プールが有効になっている既存のクラスターにスポット ノード プールを追加する必要があります。 複数のノード プールを含む AKS クラスターの作成の詳細については、「 複数のノード プールを使用する」を参照してください。

az aks nodepool add コマンドを使用してノード プールを作成します。

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name spotnodepool \
    --priority Spot \
    --eviction-policy Delete \
    --spot-max-price -1 \
    --enable-cluster-autoscaler \
    --min-count 1 \
    --max-count 3 \
    --no-wait

既定では、複数のノード プールを含む AKS クラスターを作成する場合は、その AKS クラスター内に Regularpriority を持つノード プールを作成します。 上のコマンドは、Spotpriority を持つ既存の AKS クラスターに補助ノード プールを追加します。 Spotpriority により、ノード プールがスポット ノード プールになります。 上の例では、eviction-policy パラメーターは、既定値である Delete に設定されています。 eviction policyDelete に設定すると、ノード プールの基になるスケール セット内のノードは、排除されたときに削除されます。 また、eviction policy を Deallocate に設定することもできます。 eviction policy を Deallocate に設定すると、基になるスケール セット内のノードは、排除時に停止済み/割り当て解除済み状態に設定されます。 停止済み/割り当て解除済み状態のノードはコンピューティング クォータには含まれず、クラスターのスケーリングやアップグレードで問題を発生させる場合があります。 priority および eviction-policy 値は、ノード プールの作成中にのみ設定できます。 これらの値を後で更新することはできません。

このコマンドではまた、スポット ノード プールで使用することが推奨されるクラスター オートスケーラーも有効になります。 クラスターで実行されているワークロードに基づいて、クラスター オートスケーラーは、ノード プール内のノードの数をスケールアップおよびスケールダウンします。 スポット ノード プールでは、追加のノードが引き続き必要な場合、クラスター オートスケーラーは排除の後にノードの数をスケールアップします。 ノード プールに含めることができるノードの最大数を変更する場合は、クラスター オートスケーラーに関連付けられている maxCount 値も調整する必要があります。 クラスター オートスケーラーを使用しない場合は、排除により、スポット プールが最終的に 0 まで減少し、追加のスポット ノードを受信するための手動操作が必要になります。

重要

スポット ノード プールでは、バッチ処理ジョブやテスト環境などの、中断を処理できるワークロードのみをスケジュールしてください。 スポット ノード プールでノードの排除を処理できるワークロードのみが確実にスケジュールされるようにするには、スポット ノード プールで taint と toleration を設定することをお勧めします。 たとえば、上のコマンドでは既定で kubernetes.azure.com/scalesetpriority=spot:NoSchedule の taint を追加するため、このノード上では対応する toleration を持つポッドのみがスケジュールされます。

スポット ノード プールを確認する

ノード プールがスポット ノード プールとして追加されたを確認するには:

az aks nodepool show --resource-group myResourceGroup --cluster-name myAKSCluster --name spotnodepool

scaleSetPrioritySpot であることを確認します。

スポット ノードで実行するポッドをスケジュールするには、そのスポット ノードに適用される taint に対応する toleration とノード アフィニティを追加します。 次の例は、前の手順で使用したkubernetes.azure.com/scalesetpriority=spot:NoSchedule の taint に対応する toleration と kubernetes.azure.com/scalesetpriority=spotラベルに対応するノード アフィニティを定義する yaml ファイルの一部を示しています。

spec:
  containers:
  - name: spot-example
  tolerations:
  - key: "kubernetes.azure.com/scalesetpriority"
    operator: "Equal"
    value: "spot"
    effect: "NoSchedule"
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: "kubernetes.azure.com/scalesetpriority"
            operator: In
            values:
            - "spot"
   ...

この toleration およびノード アフィニティを持つポッドがデプロイされたら、Kubernetes は、taint およびラベルが適用されているノードでそのポッドを正常にスケジュールできます。

スポット ノード プールをアップグレードする

スポット ノード プールのアップグレードは以前はサポートされていませんでしたが、現在は使用可能な操作です。 スポット ノード プールをアップグレードすると、AKS では切断および排除通知が内部で発行されますが、ドレインは適用されません。 スポット ノード プールのアップグレードに使用できるサージ ノードはありません。 これらの変更以外では、スポット ノード プールをアップグレードするときの動作は、他の種類のノード プールと一致します。

アップグレードの詳細については、「AKS クラスターのアップグレード」と Azure CLI コマンド az aks upgrade に関するページを参照してください。

スポット プールの最大価格

リージョンと SKU に基づいて、スポット インスタンスの価格は変動します。 詳細については、Linux および Windows での価格を参照してください。

変動する価格に対して、小数点以下最大 5 桁を使用して、最大価格を米ドル (USD) で設定することができます。 たとえば、0.98765 という値は、1 時間あたり 0.98765 米国ドルの最大価格になります。 最大価格を -1 に設定すると、インスタンスは価格に基づいて排除されません。 インスタンスの価格は、使用可能な容量とクォータがある限り、現在のスポットの価格または標準インスタンスの価格のいずれか低い方になります。

次のステップ

この記事では、AKS クラスターにスポット ノード プールを追加する方法について説明しました。 すべてのノード プールのポッドを制御する方法の詳細については、「Azure Kubernetes Service (AKS) での高度なスケジューラ機能に関するベスト プラクティス」を参照してください。