AKS スポット ノード プールとクラスター自動スケーラーを使用して複数のノード プールを構成する

完了

Azure では、コストが削減され、同時にスケーラビリティが得られる Azure 仮想マシン インスタンスが提供されます。これは、中断の可能性があるワークロードに最適です。 ただし、これらの仮想マシン (VM) は、使用されていない Azure のコンピューティング容量に低価格でアクセスできますが、ハイパフォーマンス コンピューティングのシナリオは引き続きサポートされます。

会社のドローン追跡ソリューションは、多数のコンテナー化されたアプリケーションおよびサービスとして Azure Kubernetes Service (AKS) にデプロイされます。 これらのサービスの 1 つは、ドローンの飛行経路をスケジュールするバッチ処理サービスです。 顧客基盤の急拡大に伴って、バッチ処理サービスに要求が殺到し、配送のバックログが増加しています。 この状況が、遅延と顧客の不満を招いています。

バッチ処理サービス レプリカの数を自動的にスケーリングすることで、タイムリーな注文処理ができるようになります。 しかし、コンピューティング リソースのニーズに対応するために、さらにノードをデプロイする必要もあります。 Azure Monitor で使用傾向を分析することで、これらのノードが特定の時間にのみ使用されており、コスト効率が良くないことがわかりました。 バッチ処理サービスはステートレスであり、クライアントセッション データは保存されません。 次のようにして、コストを削減できることがわかっています。

  • より低コストのノード インスタンスを使用する。
  • バッチ処理用に構成されている、ノード プールのノード数を自動的にスケーリングする。

AKS でのこのコスト削減ソリューションの基盤となるインフラストラクチャについて見てみましょう。

Azure のスポット仮想マシン (スポット VM) とは

"スポット仮想マシン" は、使われていない Azure コンピューティング容量に大幅な割引価格でアクセスできるようにする VM です。 スポット VM は、Azure の既存の優先度が低い VM の代わりとなるものです。 スポット VM を使用して、次のようなワークロードを実行できます。

  • 高パフォーマンス コンピューティングのシナリオ、バッチ処理、またはビジュアル レンダリング アプリケーション。

  • 大規模なステートレス アプリケーション。

  • 継続的インテグレーション (CI) および継続的デリバリー (CD) のワークロードを含む、開発者またはテスト環境。

スポット VM の可用性

スポット VM の可用性は、容量、サイズ、リージョン、時間帯などの要因に依存します。 容量が使用可能な場合にのみ、Azure によって VM が割り当てられます。 そのため、これらの種類の VM については、サービス レベル アグリーメント (SLA) がなく、高可用性は保証されません。

スポット VM の削除ポリシー

スポット VM の既定の削除ポリシーは、Deallocate です。 リージョン内の容量が制限されている場合、Azure によって、通知から 30 秒後にスポット VM が削除されます。 Deallocate ポリシーが設定されている VM は、削除されると、停止済みで割り当て解除済み状態に移行します。 スポット容量が再び利用可能になったときに、削除された VM を再デプロイできます。 割り当て解除された VM は引き続きスポット仮想 CPU (vCPU) クォータにカウントされ、基になる割り当て済みディスクの料金が引き続き適用されます。

スポット仮想マシン スケール セットとは

スポット仮想マシン スケール セットは、Azure スポット VM をサポートする仮想マシン スケール セットです。 これらの VM は通常のスポット VM と同じように動作しますが、1 つの違いがあります。Azure のスポット VM で仮想マシン スケール セットのサポートを使用する場合は、次の 2 つの削除ポリシーから選択します。

  • Deallocate: Deallocate ポリシーは、前述の説明とまったく同じように機能します。

  • Delete: Delete ポリシーを使用すると、ディスクのコストと、クォータ制限への到達を回避できます。 Delete 削除ポリシーの場合、削除対象の VM は基になるディスクと一緒に削除されます。 スケール セットの自動スケーリング機能によって、新しい VM を作成して VM 削除の補正が自動的に試行されるようになりました。 VM の作成は保証されていませんが、削除対象の VM は vCPU クォータにカウントされなくなり、基になるディスクのコストが発生しなくなります。

    スケール セットで削除ポリシーを Delete に設定する場合にのみ、自動スケーリング機能を使用することをお勧めします。

Azure Kubernetes Service (AKS) のスポット ノード プールとは

"スポット ノード プール" は、スポット仮想マシン スケール セットを使用するユーザー ノード プールです。 AKS によって、次のような場合にスポット VM がサポートされます。

  • ユーザー ノード プールを作成する必要がある。
  • Azure スポット VM の仮想マシン スケール セット サポートによって提供されるコスト上の利点を得たい。

スポットノードプールを使用して、次のことを行います。

  • Azure の使われていない容量を活用する。
  • 削除の削除ポリシーでスケール セット機能を使用する。
  • 1 時間あたりの最大希望支払価格を定義する。
  • スポット ノード プールの使用時に、推奨される AKS Kubernetes クラスター自動スケーラーを有効にする。

たとえば、ドローン追跡アプリケーションのバッチ処理サービスをサポートするために、スポット ユーザー ノード プールを作成し、クラスター自動スケーラーを有効にすることができます。 その後、リソースの需要に合わせてさらにバッチ処理サービスをデプロイするように、水平ポッド スケーラーを構成できます。

ノードの需要が増すにつれ、クラスター自動スケーラーでスポット ノード プール内のノード数をスケール アップおよびダウンすることができます。 ノードの削除が発生した場合でも、追加のノードがまだ必要であれば、クラスター自動スケーラーにより、引き続きノード数のスケールアップが試行されます。

スポット ノード プールの制限

AKS クラスターにスポット ユーザー ノード プールを追加することを決定する前に、次の制限を考慮してください。

  • 基になるスポット スケール セットは 1 つの障害ドメインにのみデプロイされ、高可用性の保証は提供されません。
  • AKS クラスターでは、複数ノード プールのサポートを有効にする必要があります。
  • スポット ノード プールはユーザー ノード プールとしてのみ使用できます。
  • スポット ノード プールをアップグレードすることはできません。
  • スポット VM の作成は保証されていません。 スポット ノードの作成は、クラスターがデプロイされる Azure リージョンでの容量とクォータの可用性に依存します。

スポット ノード プールは、中断の可能性があるワークロードにのみ使用する必要があることにご注意ください。

重要

スポンサーシップ サブスクリプションなどの一部のサブスクリプションでは、スポット VM やスポット ノード プールを作成する機能が制限されています。 クラスターでスポット ノード プールを作成できない場合があります。

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

スポット ノード プールを AKS クラスターのシステム ノード プールにすることはできません。 まずクラスターを作成し、次に az aks nodepool add コマンドを使って新しいユーザー ノード プールを追加する必要があります。

新しいノード プールでいくつかのパラメーターを設定して、スポット ノード プールとして構成します。

優先度

新しいノード プールで、--priority パラメーターは既定で Regular に設定されています。 作成する新しいプールがスポット ノード プールであることを示すために、値を Spot に設定します。 この値は、作成後に変更することはできません。

削除ポリシー

スポット ノード プールでは、仮想マシン スケール セットを使用する必要があります。 スポット ノード プールではスポット スケール セットを使用するという以前の説明を思い出してください。 --eviction-policyDelete に設定すると、ノードと、割り当て済みでノードによって使用されている基になるディスクの両方をスケール セットで削除できるようになります。 作成後にこの値を変更することはできません。

削除ポリシーを Deallocate に設定できますが、これらのノードが削除されても、クラスターのスケーリングまたはアップグレードにつながるコンピューティング クォータに対して引き続きカウントされます。

スポット ノードの最大価格

スポット ノード プールでは、スポット ノードごとの 1 時間あたり支払い最大額を制限することでコストを最適化します。 安全な金額を設定するには、--spot-max-price パラメーターを使用します。 この値に達すると、新しく作成されたスポット ノードは削除されます。

この値は、小数点以下 5 桁までの正の値、または -1 に設定できます。 --spot-max-price の値を -1 に設定すると、ノード プールに次のような影響があります。

  • ノードが、ノードの価格に基づいて削除されることはありません。
  • 新しいノードのコストは、スポット ノードの現在の価格または標準ノードの価格のいずれか低い方に基づきます。

たとえば、値を 0.98765 に設定すると、米国ドルでのノードの最大価格は 1 時間あたり 0.98765 になります。 ノードは、この金額を超えて使用されたときに削除されます。

クラスター自動スケーラーを有効にする

--enable-cluster-autoscaler パラメーターを使用して、クラスター自動スケーラーを有効にすることをお勧めします。 クラスター自動スケーラーを使用しない場合、Azure の容量制約のためにノードが削除され、ノード プールでノード数がゼロに低下するリスクがあります。

最小ノード数

--min-count パラメーターを使用して、最小ノード数を 1 から 100 の値に設定します。 クラスター自動スケーラーを有効にするときは、最小ノード数が必要です。

最大ノード数

--max-count パラメーターを使用して、最大ノード数を 1 から 100 の値に設定します。 クラスター自動スケーラーを有効にするときは、最大ノード数が必要です。

サンプル構成

最大数が 3、最小数が 1 のスポット ノード プールを追加する az aks nodepool add コマンドの例を次に示します。 スポット ノード機能を有効にするために --enable-cluster-autoscaler が使われていることに注目してください。

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

ポッドをスポット ノード プールにデプロイする

Kubernetes でワークロードをデプロイするときに、ワークロードを実行できるノードと実行できないノードを指定する情報をスケジューラに提供できます。 ワークロードのスケジュールは、"テイント"、"容認"、または "ノード アフィニティ" を構成することによって制御します。 スポット ノードには、特定のラベルとテイントが構成されます。

テイントとは?

テイントは、特定のポッドのみをノードにスケジュールできることを示すためにノードに適用されます。 ラベルを kubernetes.azure.com/scalesetpriority:spot に設定して、スポット ノードが構成されます。

容認とは?

容認は、ポッドに適用される仕様で、これにより対応するテイントを持つノードでポッドをスケジュールできるようになりますが、これは必須ではありません。 ノード テイントを kubernetes.azure.com/scalesetpriority=spot:NoSchedule に設定して、スポット ノードが構成されます。

注意

テイントと容認は、ポッドが特定のノードに配置されることを保証するものではありません。 たとえば、ノードにテイントがない場合は、容認を持つポッドが、テイントされていないノードでスケジュールされる可能性があります。 テイントと容認のアフィニティを指定すると、この問題に対処できます。

ノード アフィニティとは?

ノード アフィニティを使用して、ノードにスケジュールされているポッドを記述します。 アフィニティは、ノードに定義されているラベルを使用して指定されます。 たとえば、AKS では、システム ポッドがスポット ノードにスケジュールされるのを防ぐために、これらのノードに対するアンチアフィニティがそのポッドに構成されます。

ポッドのマニフェスト ファイルで容認を定義する

ノード テイントの容認は、ワークロードのマニフェスト ファイルに tolerations 辞書エントリを作成することによって指定します。 この辞書では、このセクションにおいてワークロードで容認する必要があるノード テイントごとに、次のプロパティを設定します。

プロパティ 説明
key ノードで指定されたノード テイントのキーと値のペアを識別します。 たとえば、スポット ノード プールでは、キーと値のペアは kubernetes.azure.com/scalesetpriority:spot です。 キーは kubernetes.azure.com/scalesetpriority です。
operator 容認をテイントと照合できます。 既定の演算子は Equal です。 容認を照合するために Exists も指定できます。 しかし、Exists を使用する場合、次のプロパティ (value) は指定しません。
value これは、ノードで指定されているノード テイントのキーと値のペアの値部分を表します。 たとえば、キーと値のペアが kubernetes.azure.com/scalesetpriority:spot のスポット ノード プールでは、値は spot となります。
effect これは、ポッドのスケジュールがシステムでどのように処理されるかを示します。 NoSchedulePreferNoScheduleNoExecute という 3 つのオプションがあります。 NoSchedule により、システムによってポッドがスケジュールされないようになります。 PreferNoSchedule を使用すると、システムでポッドのスケジュールを試行できなくなります。 NoExecute を使用すると、テイント付きのノードで既に実行されているポッドが削除されるか、ポッドがまったくスケジュールされないようになります。

ポッド マニフェスト ファイルでノード アフィニティを定義する

アフィニティを指定するには、ワークロード マニフェスト ファイルに affinity エントリを作成します。 このエントリでは、ワークロードが一致する必要があるノード ラベルごとに次のプロパティを設定します。

プロパティ 説明
nodeAffinity ポッドのノード アフィニティ スケジューリング規則について説明します。
requiredDuringSchedulingIgnoredDuringExecution このフィールドで指定されたアフィニティ要件がスケジュール時に満たされていない場合、ポッドをノードにスケジュールすることはできません。 このフィールドで指定されたアフィニティ要件が、ポッドの実行中のある時点で (更新などによって) 満たされなくなる場合、システムはポッドをそのノードから削除することを選択できます。
nodeSelectorTerms ノード セレクターの用語の一覧。 返される用語は、すべてのフィルターではなく、いずれかのフィルターに一致します。
matchExpressions ノードのラベル別のノード セレクター要件の一覧。
key セレクターが適用されるラベル キー。 キーは kubernetes.azure.com/scalesetpriority です。
operator キーと値のセットとのリレーションシップを表します。 有効な演算子は InNotInExistsDoesNotExistGt、および Lt です。
values これは、ノードで指定されているノード ラベルのキーと値のペアの値部分を表します。 キーと値のペアが kubernetes.azure.com/scalesetpriority:spot のスポット ノード プールでは、値は spot となります。

スポット ノード プールに容認およびアフィニティ追加されたワークロードの例を次に示します。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  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"

知識を確認

1.

オンライン注文を処理し、Azure Kubernetes Service (AKS) クラスターで実行されるステートレス サービスがあるとします。 クラスターのコンピューティング コストを最適化するために、AKS クラスターでスポット ノード プールを使用することにしました。 AKS クラスターにスポット ノード プールを追加するにはどうすればよいですか?

2.

前の質問で説明されているサービスについて、スポット ノード プールを構成するのに最もコスト効率の良いオプションはどの削除ポリシーですか?

3.

前の質問で説明されているサービスについて、スポット ユーザー ノード プールのノードにワークロードが確実にスケジュールされるようにするにはどうすればよいですか?