

 **このページの改善にご協力ください** 

このユーザーガイドに貢献するには、すべてのページの右側のペインにある「**GitHub でこのページを編集する**」リンクを選択してください。

# EKS Auto Mode と Karpenter を使用して AI/ML ワークロードのコンピューティングを管理する
<a name="ml-node-pools"></a>

**ヒント**  
 今後開催予定の Amazon EKS AI/ML ワークショップに[登録](https://events.eksworkshop.com/workshops/genai/)してください。

このセクションでは、Amazon EKS Auto Mode またはセルフマネージド Karpenter を使用して、AI トレーニングおよび推論ワークロードの高速コンピューティング (AWS Trainium、NVIDIA GPUs) を管理する方法について説明します。

EKS Auto Mode と Karpenter は、動的プロビジョニングと静的プロビジョニングの 2 つのプロビジョニングモードをサポートしています。動的プロビジョニングでは、EKS Auto Mode と Karpenter は、ワークロードがクラスター上でスケジュールされたときに、高速コンピューティングインスタンスをプロビジョニングしてスケーリングします。静的プロビジョニングでは、EKS Auto Mode と Karpenter は固定数のノードをプロビジョニングして維持します。動的プロビジョニングと静的プロビジョニングを同じクラスターで使用して、ワークロードの需要に応じてスケーリングしながら、一定のベースラインキャパシティプールを維持できます。

EKS Auto Mode と Karpenter は、4 つのキャパシティ購入オプション (オンデマンド、スポット、キャパシティブロック、ODCR) をすべてサポートし、常にリザーブドキャパシティを最初にプロビジョニングし、続いて Spot または On-Demand をプロビジョニングします。

## EKS Auto Mode と Karpenter の比較
<a name="eks-aiml-auto-mode-vs-karpenter"></a>

どちらのアプローチも NodePool API を共有しますが、運用所有権、リソース API、オペレーティングシステムのサポート、Spot 中断処理、設定の柔軟性が異なります。


| 機能 | EKS 自動モード | セルフマネージド Karpenter | 
| --- | --- | --- | 
| 適しているチーム | 運用上のオーバーヘッドを最小限に抑えたマネージドインフラストラクチャを好むチーム | ノードのライフサイクル、AMI、OS チューニング、パッチ適用を完全に制御したいチーム。 | 
| 運用モデル |  AWS は、Karpenter コントローラー、GPU/Trainium ドライバー、デバイスプラグイン、OS パッチ適用、Spot 中断処理をプロビジョニングおよび管理します。 | Karpenter コントローラーをクラスターにインストールして運用し、独自の GPU/Trainium ドライバー、デバイスプラグイン、AMI ライフサイクル、パッチ適用、Spot 中断処理を行います。 | 
| コンピューティングオプション | On-Demand、Spot、ODCR、機械学習用のキャパシティブロック | On-Demand、Spot、ODCR、機械学習用のキャパシティブロック | 
| リソース API |  `NodePool` (`karpenter.sh/v1`), `NodeClass` (`eks.amazonaws.com/v1`). |  `NodePool` (`karpenter.sh/v1`), `EC2NodeClass` (`karpenter.k8s.aws/v1`). | 
| ノードオペレーティングシステム | Bottlerocket のみ。NVIDIA GPU、AWS Trainium、EFA の依存関係が含まれています。 | AL2023、Bottlerocket、Windows、または独自の AMI。 | 
| ノード存続期間 | セキュリティパッチ適用の最大ノード存続期間は 21 日です。ワークロードはノードのローテーションを許容する必要があります。 | NodePool `expireAfter` と中断予算を使用してノードのライフサイクルを定義します。 | 
| Spot 中断処理 | ネイティブ。SQS キューまたはノード終了ハンドラーは必要ありません。 | 設定および有効化はユーザーの責任です。 | 
| 高速コンテナプル | すべての G、P、および Trn ファミリーインスタンスに含まれる SOCI 並列プル | 設定および有効化はユーザーの責任です。 | 
| EC2 プレイスメントグループ | クラスター、パーティション、スプレッド | クラスター、パーティション、スプレッド | 
| ネットワークインターフェイスの設定 | タイプ `interface` または `EFA-only` のインターフェイス設定ごと  | タイプ `interface` または `EFA-only` のインターフェイス設定ごと  | 
| ノードの修復 | デフォルトで有効、EKS ノードモニタリングエージェントが含まれています | オプションで有効、EKS ノードモニタリングエージェントセルフマネージド | 
| 料金 |  基盤となる EC2 インスタンスコストに加えて [EKS Auto Mode 管理料金](https://aws.amazon.com/eks/pricing/)。 | オープンソース。基盤となる EC2 インスタンスに対して料金が発生します。 | 

## 一般的な AI/ML のよく知られているラベル
<a name="eks-aiml-labels"></a>

EKS Auto Mode と Karpenter は、インスタンスタイプをハードコーディングせずにワークロードをターゲットにするために NodePool `requirements` と Pod `nodeSelector` または `nodeAffinity` で使用できるインスタンスラベルを公開します。ラベルプレフィックスは 2 つで異なります。EKS Auto Mode は `eks.amazonaws.com/` を使用し、セルフマネージド Karpenter は `karpenter.k8s.aws/` を使用します。

以下の表は、NodePools で使用できる関連ラベルを示しています。EKS Auto Mode と Karpenter は、ワークロードのターゲティングにさらに使用できるプロビジョニングプロセスの一環として、[Karpenter ドキュメント](https://karpenter.sh/docs/concepts/scheduling/#labels)に記載されているラベルをノードにも適用します。

------
#### [ EKS Auto Mode ]

完全なリストについては、「[EKS Auto Mode でサポートされているラベル](https://docs.aws.amazon.com/eks/latest/userguide/create-node-pool.html#auto-supported-labels)」を参照してください。


| ラベル | 値の例 | 説明 | 
| --- | --- | --- | 
|  `eks.amazonaws.com/instance-family`  |  `p5`  | プロパティが類似していてリソース量が異なるインスタンスタイプ。 | 
|  `eks.amazonaws.com/instance-category`  |  `p`  | インスタンスカテゴリ。通常は生成番号の前の文字。 | 
|  `eks.amazonaws.com/instance-generation`  |  `5`  | カテゴリ内のインスタンスタイプ生成番号。 | 
|  `eks.amazonaws.com/instance-gpu-name`  |  `h100`  | インスタンス上の GPU の名前。 | 
|  `eks.amazonaws.com/instance-gpu-manufacturer`  |  `nvidia`  | GPU メーカーの名前。 | 
|  `eks.amazonaws.com/instance-gpu-count`  |  `8`  | インスタンス上の GPU の数。 | 
|  `eks.amazonaws.com/instance-gpu-memory`  |  `81920`  | GPU あたりのメモリのメビバイト。 | 
|  `karpenter.sh/capacity-type`  |  `reserved`  | キャパシティタイプ: `spot`、`on-demand`、または `reserved`。 | 
|  `topology.kubernetes.io/zone`  |  `us-east-1a`  | アベイラビリティーゾーン。 | 

------
#### [ Self-managed Karpenter ]

詳細なリストについては、「[Karpenter のよく知られているラベル](https://karpenter.sh/docs/concepts/scheduling/#well-known-labels)」を参照してください。


| ラベル | 値の例 | 説明 | 
| --- | --- | --- | 
|  `karpenter.k8s.aws/instance-family`  |  `p5`  | プロパティが類似していてリソース量が異なるインスタンスタイプ。 | 
|  `karpenter.k8s.aws/instance-category`  |  `p`  | インスタンスカテゴリ。通常は生成番号の前の文字。 | 
|  `karpenter.k8s.aws/instance-generation`  |  `5`  | カテゴリ内のインスタンスタイプ生成番号。 | 
|  `karpenter.k8s.aws/instance-gpu-name`  |  `h100`  | インスタンス上の GPU の名前。 | 
|  `karpenter.k8s.aws/instance-gpu-manufacturer`  |  `nvidia`  | GPU メーカーの名前。 | 
|  `karpenter.k8s.aws/instance-gpu-count`  |  `8`  | インスタンス上の GPU の数。 | 
|  `karpenter.sh/capacity-type`  |  `reserved`  | キャパシティタイプ: `spot`、`on-demand`、または `reserved`。 | 
|  `topology.kubernetes.io/zone`  |  `us-east-1a`  | アベイラビリティーゾーン。 | 
|  `kubernetes.io/arch`  |  `amd64`  | CPU アーキテクチャ。 | 

------

## リザーブドキャパシティのスケジューリングラベル
<a name="eks-aiml-scheduling-labels"></a>

EKS Auto Mode または Karpenter が予約にノードを起動すると、次のラベルが追加されます。ワークロードをルーティングするには、`nodeSelector`、ノードアフィニティ、または NodePool の要件でこれらを使用します。
+  `karpenter.sh/capacity-type`: `reserved`、`on-demand` または `spot`。ノードをバックアップするキャパシティを示します。
+  `karpenter.k8s.aws/capacity-reservation-id`: ノードが起動された特定の予約 ID。
+  `karpenter.k8s.aws/capacity-reservation-type`: ODCR では `default`、キャパシティブロックでは `capacity-block`。

次の例は、一般的なスケジューリングパターンを示しています。

 **Pod を 1 つの特定の予約にピン留めする (フォールバックなし):** 

```
spec:
  nodeSelector:
    karpenter.sh/capacity-type: reserved
    karpenter.k8s.aws/capacity-reservation-id: "cr-0123456789abcdef0"
```

 **ターゲット ODCR ノードのみ (キャパシティブロックではなく任意の ODCR):** 

```
spec:
  nodeSelector:
    karpenter.sh/capacity-type: reserved
    karpenter.k8s.aws/capacity-reservation-type: default
```

 **リザーブドキャパシティ (ODCR またはキャパシティブロック) をターゲットにします。**

```
spec:
  nodeSelector:
    karpenter.sh/capacity-type: reserved
```

 **リザーブドを優先しますが、利用できない場合は Spot または On-Demand にフォールバックします。**

```
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          preference:
            matchExpressions:
              - key: karpenter.sh/capacity-type
                operator: In
                values: ["reserved"]
```

## 予約の有効期限の動作
<a name="eks-aiml-node-pools-expiration"></a>

予約が終了したときに、ODCR とキャパシティブロックの動作が異なります。スケジューリングとチェックポイント戦略が、ワークロードをサポートする予約のタイプと一致していることを確認します。

 **ODCR** 

ODCR に起動されたインスタンスは、その ODCR に無期限に存在するわけではありません。ODCR は期限切れになるか、キャンセルされる可能性があるか、またはインスタンスを ODCR から手動で削除される可能性があります。これらのいずれかが発生し、インスタンスが ODCR に属していないことを EKS Auto Mode/Karpenter が検出した場合、ノードの `karpenter.sh/capacity-type` ラベルが `reserved` から `on-demand` に更新されます。インスタンスは標準の On-Demand キャパシティとして実行され続け、既存の Pod は中断なく実行され続けます。

**注記**  
厳密な `nodeSelector: karpenter.sh/capacity-type: reserved` でスケジュールされた Pod は、再度ラベルが付けられている場合、ノードにスケジュールされません。ワークロードが ODCR の有効期限またはキャンセル後も存続するには、`nodeSelector` の代わりに上記の `preferredDuringSchedulingIgnoredDuringExecution` パターンを使用します。

 **キャパシティブロック** 

ODCR とは異なり、キャパシティブロックには常に終了時間があり、EC2 は終了時間の 30 分前 (UltraServer インスタンスタイプの場合は 60 分前) にキャパシティブロックインスタンスを終了します。予約ウィンドウが閉じる前に、トレーニングジョブと推論ジョブが完了するか状態を保存するように計画してください。特定の `capacity-reservation-id` に対して厳密な `nodeSelector` を使用する Pod は、ブロックの有効期限が切れると `Pending` になり、他の場所では再スケジュールされません。キャパシティブロックの有効期間中にワークロードを他のキャパシティに移動する必要がある場合は、チェックポイントの作成と上記の柔軟なアフィニティパターンを組み合わせてください。
+ ほとんどのインスタンスタイプでは、キャパシティブロックの終了時間の 30 分前まで、UltraServer インスタンスタイプでは終了時間の 60 分前まで、予約済みインスタンスを使用できます。
+ EKS Auto Mode と Karpenter は、EC2 が終了を開始する 10 分前にキャパシティブロック内のノードのドレインを事前に開始するため、ワークロードにはチェックポイントの作成とグレースフルシャットダウンの時間があります。

## 静的キャパシティ NodePool
<a name="eks-aiml-static-capacity-nodepools"></a>

EKS Auto Mode と Karpenter は、*静的キャパシティ* NodePool をサポートしており、これはワークロードの需要に関係なく決まった数のノードを維持します。静的プールは、レイテンシーの影響を受けやすい推論のコールドスタート遅延を排除し、クラスターの最小限のインフラストラクチャフットプリントを確保できます。

静的キャパシティは、NodePool 上に `replicas` フィールドを設定することで構成されます。

 **考慮事項** 
+ NodePool 上に `replicas` が設定されると、それを削除することはできません。単一の NodePool で静的キャパシティのプロビジョニングと動的キャパシティのプロビジョニングを切り替えることはできません。
+ 静的キャパシティ NodePool は、統合の対象と見なされません。`limits.nodes` を `replicas` より大きく設定して、AMI のドリフトまたは有効期間中に一時的なスケーリングを許可します。
+ 予測可能なアベイラビリティーゾーン (AZ) ディストリビューションでは、単一のプールで複数のゾーンにまたがるのではなく、AZ ごとに 1 つの静的キャパシティ NodePool を作成します。

------
#### [ EKS Auto Mode ]

以下の例は、デフォルトの EKS Auto Mode NodeClass を使用し、最大 6 個のノード (`limits.nodes`) にできる 4 個のノード (`replicas`) を持つ静的 NodePool を作成する静的キャパシティ NodePool を示しています。

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-static-inference
spec:
  replicas: 4
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6e"]
        - key: "topology.kubernetes.io/zone"
          operator: In
          values: ["us-east-1a"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
  limits:
    nodes: 6   # Allow temporary headroom during node replacement
```

------
#### [ Self-managed Karpenter ]

セルフマネージド Karpenter では、静的キャパシティはアルファ `StaticCapacity` 機能 (Karpenter バージョン v1.8 で導入) によってゲートされます。これは Helm 値で有効にする必要があります。

```
settings:
  featureGates:
    staticCapacity: true
```

NodePool は `my-nodeclass` という名前のカスタム `EC2NodeClass` を参照し、最大 6 個のノード (`limits.nodes`) にできる 4 個のノード (`replicas`) を持つ静的 NodePool を作成します。

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-static-inference
spec:
  replicas: 4
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: my-nodeclass
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6e"]
        - key: "topology.kubernetes.io/zone"
          operator: In
          values: ["us-east-1a"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
  limits:
    nodes: 6   # Allow temporary headroom during node replacement
```

------

## 機械学習用のキャパシティブロック
<a name="eks-aiml-capacity-blocks"></a>

 [機械学習用のキャパシティブロック](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-blocks.html)を使用すると、定義された今後のウィンドウ用に P ファミリーインスタンスと Trainium インスタンスを予約できます。これらは前払いであるため、EKS Auto Mode と Karpenter はそれらを無料としてモデル化し、On-Demand と Spot よりも優先します。機械学習用のキャパシティブロックには、1～14 日、または最大 182 日 (6 か月) の 7 日間の倍数のキャパシティブロックの予約期間があります。

EKS Auto Mode または Karpenter で機械学習用のキャパシティブロックを使用するには、NodeClass のキャパシティ予約 ID を使用して `capacityReservationSelectorTerms` を設定します。機械学習用のキャパシティブロックでオープン予約一致を使用することはできません。条件では、選択する ID、タグのセット、またはインスタンス一致条件を指定できます。タグを指定すると、一致するタグを持つアカウントからアクセス可能なすべてのキャパシティ予約が選択されます。これは、所有者アカウント ID を指定することでさらに制限できます。

詳細な例については、[Karpenter のドキュメント](https://karpenter.sh/docs/concepts/nodeclasses/#speccapacityreservationselectorterms)を参照してください。

------
#### [ EKS Auto Mode ]

キャパシティブロックの予約を参照する `NodeClass` を作成してから、それを使用する NodePool を作成します。

`consolidateAfter: Never` を設定すると、Karpenter はコストを削減したりワークロードをより効率的にパックしたりするために、ノードの置き換え、マージ、終了を試みません。これは、キャパシティが既に前払いされているため、キャパシティブロックに推奨されます。

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: capacity-block-gpu
spec:
  capacityReservationSelectorTerms:
    - id: "cr-0123456789abcdef0"   # Your Capacity Block reservation ID
    # Alternative: select by tags
    # - tags:
    #     role: "production-inference"
    #   owner: "012345678901"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-capacity-block
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: Never
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: capacity-block-gpu
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["reserved"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["p5", "p5e", "p5en", "p4d"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------
#### [ Self-managed Karpenter ]

`capacityReservationSelectorTerms` に加えて、AMI、サブネット、セキュリティグループセレクタを含む `EC2NodeClass` を作成してから、それを使用する NodePool を作成します。

`consolidateAfter: Never` を設定すると、Karpenter はコストを削減したりワークロードをより効率的にパックしたりするために、ノードの置き換え、マージ、終了を試みません。これは、キャパシティが既に前払いされているため、キャパシティブロックに推奨されます。

```
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: capacity-block-gpu
spec:
  amiSelectorTerms:
    - alias: al2023@latest
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: ml-cluster
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: ml-cluster
  capacityReservationSelectorTerms:
    - id: "cr-0123456789abcdef0" # Your Capacity Block reservation ID
    # Alternative: select by tags
    # - tags:
    #     role: "production-inference"
    #   owner: "012345678901"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-capacity-block
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: Never
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: capacity-block-gpu
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["reserved"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["p5", "p5e", "p5en", "p4d"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------

## On-Demand キャパシティ予約 (ODCR)
<a name="eks-aiml-odcrs"></a>

ODCR は、長期的なコミットメントなしに、特定のアベイラビリティーゾーン (AZ) のキャパシティを保証します。キャパシティが使用されているかどうかにかかわらず、標準 On-Demand 料金で請求されます。ODCR は、機械学習用のキャパシティブロックでサポートされていない G ファミリーインスタンスを含む、すべての NVIDIA GPU ファミリーをサポートします。ODCR は前払いであるため、EKS Auto Mode と Karpenter はそれらを無料としてモデル化し、On-Demand と Spot よりも優先します。

ODCR は予約の終了時に機械学習用のキャパシティブロックとは異なる動作をします。ODCR の有効期限が切れるかキャンセルされると、インスタンスは標準 On-Demand として実行され続けます。詳細については、「[予約の有効期限の動作](#eks-aiml-node-pools-expiration)」を参照してください。

EKS Auto Mode または Karpenter で ODCR を使用するには、NodeClass のキャパシティ予約条件を使用して `capacityReservationSelectorTerms` を設定します。条件では、選択する ID、タグのセット、またはインスタンス一致条件を指定できます。タグを指定すると、一致するタグを持つアカウントからアクセス可能なすべてのキャパシティ予約が選択されます。インスタンス一致条件を指定すると、一致する動作で予約が選択されます: open (互換性のあるすべてのインスタンスに一致) または targeted (明示的にターゲットされたインスタンスにのみ一致)。これは、所有者アカウント ID を指定することでさらに制限できます。

詳細な例については、[Karpenter のドキュメント](https://karpenter.sh/docs/concepts/nodeclasses/#speccapacityreservationselectorterms)を参照してください。

------
#### [ EKS Auto Mode ]

`capacityReservationSelectorTerms` を使用して `NodeClass` を作成し、`on-demand` フォールバックで `reserved` を優先する NodePool を作成します。`topology.kubernetes.io/zone` を ODCR の AZ にピン留めします。

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: odcr-gpu-production
spec:
  capacityReservationSelectorTerms:
    - id: "cr-0987654321fedcba0"
    # Alternative: select by tags
    # - tags:
    #     Purpose: "production-inference"
    #   owner: "012345678901"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-reserved-production
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: Never
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: odcr-gpu-production
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["reserved", "on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["p5", "g6e"]
        - key: "topology.kubernetes.io/zone"
          operator: In
          values: ["us-east-1a"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------
#### [ Self-managed Karpenter ]

`capacityReservationSelectorTerms` に加えて、`EC2NodeClass` を AMI、サブネット、セキュリティグループセレクタを使用して作成してから、NodePool を作成します。

```
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: odcr-gpu-production
spec:
  amiSelectorTerms:
    - alias: al2023@latest
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: ml-cluster
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: ml-cluster
  capacityReservationSelectorTerms:
    - id: "cr-0987654321fedcba0"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-reserved-production
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: Never
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: odcr-gpu-production
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["reserved", "on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["p5", "g6e"]
        - key: "topology.kubernetes.io/zone"
          operator: In
          values: ["us-east-1a"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------

## On-Demand
<a name="eks-aiml-on-demand"></a>

On-Demand はデフォルトのキャパシティタイプであり、EKS Auto Mode および Karpenter の静的または動的なプロビジョニングで使用できます。NodePool で `karpenter.sh/capacity-type: on-demand` を設定することで、オンデマンドインスタンスを明示的にリクエストできます。EKS Auto Mode と Karpenter は、Pod のリソースリクエストを満たす最低価格のインスタンスを選択します。開発、プロトタイプ作成、予測不可能な推論スケーリング、および中断リスクなしで即時の可用性を必要とするワークロードには、On-Demand を使用します。

------
#### [ EKS Auto Mode ]

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-ondemand
spec:
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6", "g6e", "g7e"]
        - key: "karpenter.k8s.aws/instance-gpu-manufacturer"
          operator: In
          values: ["nvidia"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------
#### [ Self-managed Karpenter ]

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-ondemand
spec:
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6", "g6e", "g7e"]
        - key: "karpenter.k8s.aws/instance-gpu-manufacturer"
          operator: In
          values: ["nvidia"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------

## Spot
<a name="eks-aiml-spot"></a>

Spot は、予備の EC2 キャパシティを使用することで、On-Demand と比較して最大 90% のコスト削減を実現します。AWS は、2 分間の中断通知でスポットインスタンスを再利用できます。NodePool 上で複数のインスタンスファミリーを一覧表示して可用性を最大化します。Spot ワークロードを `PodDisruptionBudget` とペアリングし、耐久性のあるストレージ (Amazon S3 または Amazon EFS) に定期的にチェックポイントを保存して、Pod がドレインウィンドウ中に状態を保存できるようにします。

Spot スポットは、耐障害性があり、再開可能なトレーニングや推論のワークロードに適しています。ここでは、大幅なコスト削減と引き換えに、一時的な中断が許容されます。

一般的な候補には、以下が含まれます。
+  **ハイパーパラメータのチューニングとスイープ**: 中断した場合に再試行できる多くの短い並列トライアル。
+  **チェックポイントを使用した分散トレーニング**: 状態を S3 または FSx に定期的に保存し、ノードの損失後に最後のチェックポイントから再開できる長時間実行されるジョブ。
+  **バッチ推論とオフライン推論**: エンドツーエンドのレイテンシーが秒単位ではなく時間単位で測定されるデータセットに対する大規模なスコアリングジョブ。
+  **データ前処理と特徴量エンジニアリングパイプライン**: 大規模なデータセットでの並列変換。
+  **モデル評価とベンチマーク**: べき等の結果を生成する反復可能なジョブ。
+  **開発、プロトタイプ、ノートブック**: ユーザーがときどき再起動を許容できるインタラクティブな実験。

レイテンシーの影響を受けやすいリアルタイム推論、SLA バインドされた本番稼働用エンドポイント、チェックポイントがない、または再起動を許容できないワークロードには Spot の使用を避けてください。

NodePool で `karpenter.sh/capacity-type: spot` を設定することで、スポットインスタンスを明示的にリクエストできます。

------
#### [ EKS Auto Mode ]

EKS Auto Mode は Spot 中断をネイティブに処理します。SQS キューまたはノード終了ハンドラーは必要ありません。

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-spot
spec:
  disruption:
    budgets:
      - nodes: 10%
    consolidationPolicy: WhenEmpty
    consolidateAfter: 1h
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["spot"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6", "g6e", "g7e"]
        - key: "karpenter.k8s.aws/instance-gpu-manufacturer"
          operator: In
          values: ["nvidia"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
  limits:
    resources:
      nvidia.com/gpu: "64"
```

------
#### [ Self-managed Karpenter ]

セルフマネージド Karpenter では、EC2 Spot 中断イベントと[再調整レコメンデーション](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/rebalance-recommendations.html)イベントを受信する SQS キューである中断キューを設定することで、Karpenter コントローラー上で (NodePool 上ではなく) ネイティブ中断処理を有効にする必要があります。これをインストール時に 1 回設定します。

Helm で Karpenter を直接インストールする場合は、`settings.interruptionQueue` で `values.yaml` を設定します。

```
# karpenter values.yaml (Helm)
settings:
  clusterName: my-cluster
  interruptionQueue: my-queue   # Name of the SQS queue receiving Spot events
```

`eksctl` で Karpenter をブートストラップする場合は、クラスター設定ファイルに `withSpotInterruptionQueue: true` を設定します。`eksctl` は SQS キューと EventBridge ルールを作成し、それらを使用するように Karpenter コントローラーを設定します。

```
# eksctl ClusterConfig
karpenter:
  version: "${KARPENTER_VERSION}"
  withSpotInterruptionQueue: true
```

コントローラーがキューを使用するようにセットアップされると、個々の NodePool リソースに追加の設定は必要ありません。中断処理はクラスター全体に適用されます。

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-spot
spec:
  disruption:
    budgets:
      - nodes: 10%
    consolidationPolicy: WhenEmpty
    consolidateAfter: 1h
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["spot"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6", "g6e", "g7e"]
        - key: "karpenter.k8s.aws/instance-gpu-manufacturer"
          operator: In
          values: ["nvidia"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
  limits:
    resources:
      nvidia.com/gpu: "64"
```

------