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

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

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

スポット ノード プールをデプロイすると、使用可能な容量がある場合、Azure はスポット ノードを割り当て、スポット ノード プールを支援するスポット スケール セットを 1 つの既定のドメインにデプロイします。 スポット ノードの SLA は存在しません。 高可用性の保証はありません。 容量が Azure で再び必要になると、Azure インフラストラクチャはスポット ノードを削除します。

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

開始する前に

  • この記事は、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 クラスターを作成する場合、既定では、Regularpriority を持つノード プールを作成します。 スポット ノード プールを追加するには、priority の値として Spot を指定する必要があります。 複数のノード プールを含む AKS クラスターの作成の詳細については、「 複数のノード プールを使用する」を参照してください。

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

    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
    

前のコマンドでは、Spotpriority により、ノード プールがスポット ノード プールになります。 eviction-policy パラメーターは Delete に設定されています。これは既定値です。 eviction policyDelete に設定すると、ノード プールの基になるスケール セット内のノードは、排除されたときに削除されます。

eviction policy を Deallocate に設定することもできます。これは、基になるスケール セット内のノードが、排除時に "停止済み/割り当て解除済み" 状態に設定されることを意味します。 "停止済み/割り当て解除済み" 状態のノードはコンピューティング クォータには含まれず、クラスターのスケーリングやアップグレードで問題を発生させる場合があります。 priority および eviction-policy 値は、ノード プールの作成中にのみ設定できます。 これらの値を後で更新することはできません。

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

重要

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

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

  • ノード プールが追加されたことを確認するために az aks nodepool show コマンドを使用して、scaleSetPrioritySpot であることを確認します。

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

スポット ノードで実行するポッドをスケジュールする

スポット ノードで実行するポッドをスケジュールするには、そのスポット ノードに適用される taint に対応する toleration とノード アフィニティを追加できます。

次の例は、requiredDuringSchedulingIgnoredDuringExecution および preferredDuringSchedulingIgnoredDuringExecution ノード アフィニティ ルールを含む前の手順で使用した 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"
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value

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

  • ノードはキー kubernetes.azure.com/scalesetpriority を持つラベルを持つ必要があり、そのラベルの値は spot である必要があります
  • ノードには、できるだけキー another-node-label-key を持つラベルがあり、そのラベルの値は another-node-label-value である必要があります

詳しくは、「ノードへのポッドの割り当て」をご覧ください。

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

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

アップグレードの詳細については、「AKS クラスターのアップグレード」を参照してください。

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

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

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

次のステップ

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