

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Karpenter
<a name="karpenter"></a>

**ヒント**  
 Amazon EKS [https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el)ワークショップを通じてベストプラクティスをご覧ください。

 [Karpenter](https://karpenter.sh/) は、Kubernetes クラスター内のノードライフサイクル管理を強化するように設計されたオープンソースプロジェクトです。ポッドの特定のスケジューリングニーズに基づいてノードのプロビジョニングとプロビジョニング解除を自動化し、効率的なスケーリングとコスト最適化を可能にします。その主な関数は次のとおりです。
+ リソースの制約により Kubernetes スケジューラがスケジュールできないポッドをモニタリングします。
+ スケジューリング不可能なポッドのスケジューリング要件 (リソースリクエスト、ノードセレクタ、アフィニティ、許容範囲など) を評価します。
+ これらのポッドの要件を満たす新しいノードをプロビジョニングします。
+ 不要になったノードを削除します。

Karpenter を使用すると、テイント、ラベル、要件 (インスタンスタイプ、ゾーンなど）、プロビジョニングされたリソースの合計の制限など、ノードのプロビジョニングに制約がある NodePools を定義できます。ワークロードをデプロイするときは、リソースリクエスト/制限、ノードセレクタ、ノード/ポッドアフィニティ、許容範囲、トポロジースプレッド制約など、ポッド仕様でさまざまなスケジューリング制約を指定できます。Karpenter は、これらの仕様に基づいて適切なサイズのノードをプロビジョニングします。

 **Karpenter を使用する理由** 

Karpenter のリリース前は、Kubernetes ユーザーは主に [Amazon EC2 Auto Scaling グループ](https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroup.html)と [Kubernetes Cluster Autoscaler](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler) (CAS) に依存して、クラスターのコンピューティング性能を動的に調整していました。Karpenter を使用すると、Karpenter で得られる柔軟性と多様性を実現するために、数十のノードグループを作成する必要はありません。CAS とは異なり、Karpenter は Kubernetes バージョンとそれほど緊密に結合されておらず、AWS API と Kubernetes APIs の間でジャンプする必要はありません。

Karpenter は、インスタンスオーケストレーションの責任を 1 つのシステムに統合します。これにより、よりシンプルで安定したクラスター対応が可能になります。Karpenter は、以下の簡単な方法を提供することで、Cluster Autoscaler が提供するいくつかの課題を克服するように設計されています。
+ ワークロードの要件に基づいてノードをプロビジョニングします。
+ 柔軟な NodePool オプションを使用して、インスタンスタイプごとに多様なノード設定を作成します。Karpenter は、多くの特定のカスタムノードグループを管理する代わりに、単一の柔軟な NodePool で多様なワークロード容量を管理できます。
+ ノードをすばやく起動し、ポッドをスケジュールすることで、大規模なポッドスケジューリングを改善します。

Karpenter の使用に関する情報とドキュメントについては、[karpenter.sh](https://karpenter.sh/) サイトを参照してください。

## 推奨事項
<a name="_recommendations"></a>

ベストプラクティスは、Karpenter 自体、NodePools、ポッドスケジューリングのセクションに分かれています。

## Karpenter のベストプラクティス
<a name="_karpenter_best_practices"></a>

以下のベストプラクティスでは、Karpenter 自体に関連するトピックについて説明します。

### 本番稼働用クラスターの AMIs をロックダウンする
<a name="_lock_down_amis_in_production_clusters"></a>

Karpenter が本番クラスターに使用する有名な Amazon マシンイメージ (AMIs) を固定することを強くお勧めします。エイリアス`amiSelector`を に設定するか`@latest`、リリース時にテストされていない AMIs をデプロイする他の方法を使用すると、本番稼働用クラスターでワークロードの障害やダウンタイムが発生するリスクがあります。そのため、非本番稼働用クラスターで新しいバージョンをテストしながら、本番稼働用クラスターのテスト済み作業バージョンの AMIs を固定することを強くお勧めします。たとえば、次のように NodeClass にエイリアスを設定できます。

```
amiSelectorTerms
  - alias: al2023@v20240807
```

Karpenter での AMIs の管理とピンダウンの詳細については、Karpenter ドキュメントの[AMIs](https://karpenter.sh/docs/tasks/managing-amis/)」を参照してください。

### 容量のニーズが変化するワークロードに Karpenter を使用する
<a name="_use_karpenter_for_workloads_with_changing_capacity_needs"></a>

Karpenter は、Autoscaling Groups (ASGs) や [Managed Node Groups](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) (MNGs) よりも Kubernetes ネイティブ APIs に近いスケーリング管理を提供します。 [https://aws.amazon.com/blogs/containers/amazon-eks-cluster-multi-zone-auto-scaling-groups/](https://aws.amazon.com/blogs/containers/amazon-eks-cluster-multi-zone-auto-scaling-groups/)ASGs と MNGsは、EC2 CPU 負荷などの AWS レベルのメトリクスに基づいてスケーリングがトリガーされる AWS ネイティブ抽象化です。[Cluster Autoscaler](https://docs.aws.amazon.com/eks/latest/userguide/autoscaling.html#cluster-autoscaler) は Kubernetes 抽象化を AWS 抽象化にブリッジしますが、特定のアベイラビリティーゾーンのスケジュールなど、そのための柔軟性が失われます。

Karpenter は AWS 抽象化のレイヤーを削除して、柔軟性の一部を Kubernetes に直接取り込みます。Karpenter は、需要が急増したり、コンピューティング要件が多様化したワークロードを持つクラスターに最適です。MNGsと ASGs は、より静的で整合性のあるワークロードを実行するクラスターに適しています。要件に応じて、動的に管理されたノードと静的に管理されたノードを組み合わせて使用できます。

### 次の場合は、他の Auto Scaling プロジェクトを検討してください。
<a name="_consider_other_autoscaling_projects_when"></a>

Karpenter でまだ開発中の機能が必要です。Karpenter は比較的新しいプロジェクトであるため、Karpenter にまだ含まれていない機能が必要な場合は、当面、他の Auto Scaling プロジェクトを検討してください。

### EKS Fargate またはノードグループに属するワーカーノードで Karpenter コントローラーを実行する
<a name="_run_the_karpenter_controller_on_eks_fargate_or_on_a_worker_node_that_belongs_to_a_node_group"></a>

Karpenter は [Helm チャート](https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/#4-install-karpenter)を使用してインストールされます。Helm チャートは、クラスターのスケーリングにコントローラーを使用する前に実行する必要があるデプロイとして Karpenter コントローラーとウェブフックポッドをインストールします。少なくとも 1 つのワーカーノードを持つ少なくとも 1 つの小さなノードグループをお勧めします。別の方法として、`karpenter`名前空間の Fargate プロファイルを作成して、これらのポッドを EKS Fargate で実行することもできます。これにより、この名前空間にデプロイされたすべてのポッドが EKS Fargate で実行されます。Karpenter が管理するノードで Karpenter を実行しないでください。

### Karpenter でのカスタム起動テンプレートのサポートなし
<a name="_no_custom_launch_templates_support_with_karpenter"></a>

v1 APIs でのカスタム起動テンプレートのサポートはありません。カスタムユーザーデータを使用するか、EC2NodeClass でカスタム AMIs を直接指定できます。これを行う方法の詳細については、[NodeClasses](https://karpenter.sh/docs/concepts/nodeclasses/) を参照してください。

### ワークロードに合わないインスタンスタイプを除外する
<a name="_exclude_instance_types_that_do_not_fit_your_workload"></a>

クラスターで実行されているワークロードで必要でない場合は、 `node.kubernetes.io/instance-type`キーを使用して特定のインスタンスタイプを除外することを検討してください。

次の例は、大きな Graviton インスタンスのプロビジョニングを回避する方法を示しています。

```
- key: node.kubernetes.io/instance-type
  operator: NotIn
  values:
  - m6g.16xlarge
  - m6gd.16xlarge
  - r6g.16xlarge
  - r6gd.16xlarge
  - c6g.16xlarge
```

### スポットの使用時に中断処理を有効にする
<a name="_enable_interruption_handling_when_using_spot"></a>

Karpenter は[ネイティブの中断処理](https://karpenter.sh/docs/concepts/disruption/#interruption)をサポートし、スポットインスタンスの中断、スケジュールされたメンテナンスイベント、ワークロードを中断する可能性のあるインスタンスの終了/停止イベントなどの非自発的な中断イベントを処理できます。Karpenter は、ノードのこのようなイベントを検出すると、影響を受けるノードを事前に自動的に汚染、ドレイン、終了して、中断前にワークロードの正常なクリーンアップを開始します。2 分前の通知によるスポット中断の場合、Karpenter は新しいノードをすばやく開始し、インスタンスが再利用される前にポッドを移動できるようにします。中断処理を有効にするには、この目的のためにプロビジョニングされた SQS キューの名前で `--interruption-queue` CLI 引数を設定します。ここで説明するように、ノード終了ハンドラーと一緒に Karpenter 中断処理を使用することはお勧めしません[https://karpenter.sh/docs/faq/#interruption-handling](https://karpenter.sh/docs/faq/#interruption-handling)。

チェックポイントやその他の形式の正常なドレイニングが必要で、シャットダウン前に 2 分を必要とするポッドは、クラスターで Karpenter の中断処理を有効にする必要があります。

### **アウトバウンドインターネットアクセスのない Amazon EKS プライベートクラスター**
<a name="_amazon_eks_private_cluster_without_outbound_internet_access"></a>

インターネットへのルートがない VPC に EKS クラスターをプロビジョニングする場合は、EKS ドキュメントに記載されているプライベートクラスター[の要件](https://docs.aws.amazon.com/eks/latest/userguide/private-clusters.html#private-cluster-requirements)に従って環境が設定されていることを確認する必要があります。さらに、VPC に STS VPC リージョンエンドポイントが作成されていることを確認する必要があります。そうでない場合、次のようなエラーが表示されます。

```
{"level":"FATAL","time":"2024-02-29T14:28:34.392Z","logger":"controller","message":"Checking EC2 API connectivity, WebIdentityErr: failed to retrieve credentials\ncaused by: RequestError: send request failed\ncaused by: Post \"https://sts.<region>.amazonaws.com/\": dial tcp 54.239.32.126:443: i/o timeout","commit":"596ea97"}
```

Karpenter Controller はサービスアカウント (IRSA) に IAM ロールを使用するため、これらの変更はプライベートクラスターで必要です。IRSA で設定されたポッドは、AWS Security Token Service (AWS STS) API を呼び出して認証情報を取得します。アウトバウンドインターネットアクセスがない場合は、VPC ***で AWS STS VPC エンドポイント***を作成して使用する必要があります。

プライベートクラスターでは、***SSM の VPC エンドポイント***も作成する必要があります。Karpenter が新しいノードのプロビジョニングを試みると、起動テンプレート設定と SSM パラメータをクエリします。VPC に SSM VPC エンドポイントがない場合、次のエラーが発生します。

```
{"level":"ERROR","time":"2024-02-29T14:28:12.889Z","logger":"controller","message":"Unable to hydrate the AWS launch template cache, RequestCanceled: request context canceled\ncaused by: context canceled","commit":"596ea97","tag-key":"karpenter.k8s.aws/cluster","tag-value":"eks-workshop"}
...
{"level":"ERROR","time":"2024-02-29T15:08:58.869Z","logger":"controller.nodeclass","message":"discovering amis from ssm, getting ssm parameter \"/aws/service/eks/optimized-ami/1.27/amazon-linux-2/recommended/image_id\", RequestError: send request failed\ncaused by: Post \"https://ssm.<region>.amazonaws.com/\": dial tcp 67.220.228.252:443: i/o timeout","commit":"596ea97","ec2nodeclass":"default","query":"/aws/service/eks/optimized-ami/1.27/amazon-linux-2/recommended/image_id"}
```

** *[Price List Query API](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/using-pelong.html) の VPC エンドポイント***はありません。その結果、料金データは時間の経過とともに古くなります。Karpenter は、オンデマンドの料金データをバイナリに含めることでこれを回避しますが、Karpenter がアップグレードされたときにのみそのデータを更新します。料金データのリクエストに失敗すると、次のエラーメッセージが表示されます。

```
{"level":"ERROR","time":"2024-02-29T15:08:58.522Z","logger":"controller.pricing","message":"retreiving on-demand pricing data, RequestError: send request failed\ncaused by: Post \"https://api.pricing.<region>.amazonaws.com/\": dial tcp 18.196.224.8:443: i/o timeout; RequestError: send request failed\ncaused by: Post \"https://api.pricing.<region>.amazonaws.com/\": dial tcp 18.185.143.117:443: i/o timeout","commit":"596ea97"}
```

完全にプライベート EKS クラスターで Karpenter を使用し、作成する VPC エンドポイントを確認するには、この[ドキュメント](https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/#private-clusters)を参照してください。

## NodePools の作成
<a name="_creating_nodepools"></a>

以下のベストプラクティスでは、NodePools の作成に関連するトピックについて説明します。

### 次の場合に複数の NodePools を作成します。
<a name="_create_multiple_nodepools_when"></a>

異なるチームがクラスターを共有していて、異なるワーカーノードでワークロードを実行する必要がある場合、または異なる OS またはインスタンスタイプの要件がある場合は、複数の NodePools を作成します。たとえば、あるチームは Bottlerocket を使用し、別のチームは Amazon Linux を使用する場合があります。同様に、あるチームは、別のチームが必要としない高価な GPU ハードウェアにアクセスできる可能性があります。複数の NodePools を使用すると、各チームが最適なアセットを利用できるようになります。

### 相互に排他的または重み付けされた NodePoolsを作成する
<a name="_create_nodepools_that_are_mutually_exclusive_or_weighted"></a>

一貫したスケジューリング動作を提供するために、相互に排他的または重み付けされた NodePoolsを作成することをお勧めします。一致しない場合、複数の NodePoolsが一致すると、Karpenter は使用するものをランダムに選択し、予期しない結果を引き起こします。複数の NodePoolsを作成するための便利な例は次のとおりです。

GPU を使用して NodePool を作成し、特別なワークロードをこれらの (高価な) ノードでのみ実行できるようにします。

```
# NodePool for GPU Instances with Taints
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu
spec:
  disruption:
    consolidateAfter: 1m
    consolidationPolicy: WhenEmptyOrUnderutilized
  template:
    metadata: {}
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      expireAfter: Never
      requirements:
      - key: node.kubernetes.io/instance-type
        operator: In
        values:
        - p3.8xlarge
        - p3.16xlarge
      - key: kubernetes.io/os
        operator: In
        values:
        - linux
      - key: kubernetes.io/arch
        operator: In
        values:
        - amd64
      - key: karpenter.sh/capacity-type
        operator: In
        values:
        - on-demand
      taints:
      - effect: NoSchedule
        key: nvidia.com/gpu
        value: "true"
```

テイントの許容値を使用したデプロイ:

```
# Deployment of GPU Workload will have tolerations defined
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inflate-gpu
spec:
    spec:
      tolerations:
      - key: "nvidia.com/gpu"
        operator: "Exists"
        effect: "NoSchedule"
```

別のチームの一般的なデプロイでは、NodePool 仕様に nodeAffinity を含めることができます。その後、デプロイでは nodeSelectorTerms を使用して を照合できます`billing-team`。

```
# NodePool for regular EC2 instances
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: generalcompute
spec:
  template:
    metadata:
      labels:
        billing-team: my-team
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      expireAfter: Never
      requirements:
      - key: node.kubernetes.io/instance-type
        operator: In
        values:
        - m5.large
        - m5.xlarge
        - m5.2xlarge
        - c5.large
        - c5.xlarge
        - c5a.large
        - c5a.xlarge
        - r5.large
        - r5.xlarge
      - key: kubernetes.io/os
        operator: In
        values:
        - linux
      - key: kubernetes.io/arch
        operator: In
        values:
        - amd64
      - key: karpenter.sh/capacity-type
        operator: In
        values:
        - on-demand
```

nodeAffinity を使用したデプロイ:

```
# Deployment will have spec.affinity.nodeAffinity defined
kind: Deployment
metadata:
  name: workload-my-team
spec:
  replicas: 200
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: "billing-team"
                  operator: "In"
                  values: ["my-team"]
```

### タイマー (TTL) を使用してクラスターからノードを自動的に削除する
<a name="_use_timers_ttl_to_automatically_delete_nodes_from_the_cluster"></a>

プロビジョニングされたノードのタイマーを使用して、ワークロードポッドがないノードや有効期限に達したノードを削除するタイミングを設定できます。ノードの有効期限はアップグレードの手段として使用できるため、ノードは廃止され、更新されたバージョンに置き換えられます。`spec.template.spec` を使用してノード[の有効期限](https://karpenter.sh/docs/concepts/disruption/)を設定する方法については、Karpenter ドキュメントの「有効期限」を参照してください。

### Karpenter がプロビジョニングできるインスタンスタイプを過度に制約しないようにします。特にスポットを利用する場合です。
<a name="_avoid_overly_constraining_the_instance_types_that_karpenter_can_provision_especially_when_utilizing_spot"></a>

スポットを使用する場合、Karpenter は [Price Capacity Optimized](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-fleet-allocation-strategy.html) 配分戦略を使用して EC2 インスタンスをプロビジョニングします。この戦略では、起動するインスタンスの数に対して最も深いプールからインスタンスをプロビジョニングし、中断のリスクを最小限に抑えるように EC2 に指示します。次に、EC2 フリートは、これらのプールのうち最低価格のスポットインスタンスをリクエストします。Karpenter が利用できるインスタンスタイプが多いほど、EC2 はスポットインスタンスのランタイムを最適化できます。デフォルトでは、Karpenter はクラスターがデプロイされているリージョンとアベイラビリティーゾーンで EC2 が提供するすべてのインスタンスタイプを使用します。Karpenter は、保留中のポッドに基づいてすべてのインスタンスタイプのセットからインテリジェントに選択し、ポッドが適切なサイズで装備されたインスタンスにスケジュールされていることを確認します。たとえば、ポッドに GPU が必要ない場合、Karpenter は GPU をサポートする EC2 インスタンスタイプにポッドをスケジュールしません。使用するインスタンスタイプが不明な場合は、Amazon [ec2-instance-selector](https://github.com/aws/amazon-ec2-instance-selector) を実行して、コンピューティング要件に一致するインスタンスタイプのリストを生成できます。たとえば、CLI はメモリ vCPU、アーキテクチャ、リージョンを入力パラメータとして受け取り、これらの制約を満たす EC2 インスタンスのリストを提供します。

```
$ ec2-instance-selector --memory 4 --vcpus 2 --cpu-architecture x86_64 -r ap-southeast-1
c5.large
c5a.large
c5ad.large
c5d.large
c6i.large
t2.medium
t3.medium
t3a.medium
```

スポットインスタンスを使用するときは、Karpenter にあまり多くの制約を課さないでください。そうすると、アプリケーションの可用性に影響する可能性があるためです。たとえば、特定のタイプのすべてのインスタンスが再利用され、それらを置き換える適切な代替手段がないとします。ポッドは、設定されたインスタンスタイプのスポット容量が補充されるまで保留状態のままになります。スポットプールは AZs 間で異なるため、インスタンスを異なるアベイラビリティーゾーンに分散することで、容量不足エラーのリスクを減らすことができます。ただし、一般的なベストプラクティスは、Karpenter が スポットを使用するときにさまざまなインスタンスタイプのセットを使用できるようにすることです。

## ポッドのスケジューリング
<a name="_scheduling_pods"></a>

以下のベストプラクティスは、ノードプロビジョニングに Karpenter を使用するクラスターでのポッドのデプロイに関連しています。

### EKS のベストプラクティスに従って高可用性を実現する
<a name="_follow_eks_best_practices_for_high_availability"></a>

可用性の高いアプリケーションを実行する必要がある場合は、一般的な EKS ベストプラクティスの[推奨事項](https://docs.aws.amazon.com/eks/latest/best-practices/application.html#_recommendations)に従ってください。ノードとゾーンにポッドを分散する方法の詳細については、Karpenter ドキュメントの[「トポロジースプレッド](https://karpenter.sh/docs/concepts/scheduling/#topology-spread)」を参照してください。[Disruption Budgets](https://karpenter.sh/docs/troubleshooting/#disruption-budgets) を使用して、ポッドの削除または削除を試みた場合に備えて、メンテナンスが必要な利用可能な最小ポッドを設定します。

### レイヤード制約を使用して、クラウドプロバイダーから利用できるコンピューティング機能を制限する
<a name="_use_layered_constraints_to_constrain_the_compute_features_available_from_your_cloud_provider"></a>

Karpenter のレイヤード制約のモデルを使用すると、複雑な NodePool とポッドのデプロイ制約のセットを作成して、ポッドスケジューリングに最適なマッチングを取得できます。ポッド仕様がリクエストできる制約の例は次のとおりです。
+ 特定のアプリケーションのみが利用可能なアベイラビリティーゾーンで を実行する必要があります。たとえば、特定のアベイラビリティーゾーンにある EC2 インスタンスで実行される別のアプリケーションと通信する必要があるポッドがあるとします。VPC 内のクロス AZ トラフィックを減らすことが目的の場合は、EC2 インスタンスが配置されている AZ にポッドを共同配置できます。このようなターゲット設定は、多くの場合、ノードセレクタを使用して行われます。[ノードセレクタ](https://karpenter.sh/docs/concepts/scheduling/#selecting-nodes)の詳細については、Kubernetes ドキュメントを参照してください。
+ 特定の種類のプロセッサやその他のハードウェアが必要です。ポッドを GPU で実行する必要があるポッド仕様の例については、Karpenter ドキュメントの [Accelerators](https://karpenter.sh/docs/concepts/scheduling/#acceleratorsgpu-resources) セクションを参照してください。

### コンピューティング支出をモニタリングする請求アラームを作成する
<a name="_create_billing_alarms_to_monitor_your_compute_spend"></a>

クラスターを自動的にスケーリングするように設定する場合は、支出がしきい値を超えたときに警告する請求アラームを作成し、Karpenter 設定にリソース制限を追加する必要があります。Karpenter でリソース制限を設定することは、Karpenter NodePool によってインスタンス化できるコンピューティングリソースの最大量を表すという点で、AWS Auto Scaling グループの最大容量を設定することに似ています。

**注記**  
クラスター全体のグローバル制限を設定することはできません。制限は特定の NodePools に適用されます。

以下のスニペットでは、最大 1000 個の CPU コアと 1000Gi のメモリのみをプロビジョニングするように Karpenter に指示しています。Karpenter は、制限が満たされたか超えた場合にのみ容量の追加を停止します。制限を超えると、Karpenter コントローラーはコントローラーのログに `memory resource usage of 1001 exceeds limit of 1000`または同様の表示メッセージを書き込みます。コンテナログを CloudWatch Logs にルーティングする場合は、[メトリクスフィルター](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/MonitoringLogData.html)を作成してログ内の特定のパターンや用語を検索し、設定されたメトリクスのしきい値を超えたときに警告する [CloudWatch アラーム](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)を作成できます。

Karpenter で制限を使用する詳細については、Karpenter ドキュメントの[「リソース制限の設定](https://karpenter.sh/docs/concepts/nodepools/#speclimits)」を参照してください。

```
spec:
  limits:
    cpu: 1000
    memory: 1000Gi
```

Karpenter がプロビジョニングできるインスタンスタイプを制限または制限しない場合、Karpenter は必要に応じてクラスターにコンピューティング容量を追加し続けます。この方法で Karpenter を設定すると、クラスターを自由にスケールできますが、コストに大きな影響を与える可能性もあります。このため、請求アラームを設定することをお勧めします。請求アラームを使用すると、アカウントの計算された推定請求額が定義されたしきい値を超えたときに、アラートと事前通知を受け取ることができます (複数可）。詳細については、[「推定請求額をプロアクティブにモニタリングするための Amazon CloudWatch 請求アラームの設定](https://aws.amazon.com/blogs/mt/setting-up-an-amazon-cloudwatch-billing-alarm-to-proactively-monitor-estimated-charges/)」を参照してください。

また、コスト異常検出を有効にすることもできます。これは、機械学習を使用してコストと使用状況を継続的にモニタリングし、異常な支出を検出する AWS コスト管理機能です。詳細については、[AWS コスト異常検出入門](https://docs.aws.amazon.com/cost-management/latest/userguide/getting-started-ad.html)ガイドを参照してください。AWS Budgets で予算を作成するまで行った場合は、特定のしきい値を超えたときに通知するようにアクションを設定することもできます。予算アクションを使用すると、E メールを送信したり、SNS トピックにメッセージを投稿したり、Slack などのチャットボットにメッセージを送信したりできます。詳細については、[「AWS Budgets アクションの設定](https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-controls.html)」を参照してください。

### Karpenter がノードのプロビジョニングを解除しないようにするには、karpenter.sh/do-not-disrupt 注釈を使用します。
<a name="_use_the_karpenter_shdo_not_disrupt_annotation_to_prevent_karpenter_from_deprovisioning_a_node"></a>

*長時間実行される*バッチジョブやステートフルアプリケーションなど、Karpenter がプロビジョニングしたノードで重要なアプリケーションを実行し、**ノードの TTL の有効期限が切れている場合、インスタンスが終了するとアプリケーションは中断されます。ポッドに`karpenter.sh/do-not-disrupt`注釈を追加することで、ポッドが終了するか`karpenter.sh/do-not-disrupt`注釈が削除されるまでノードを保持するように Karpenter に指示します。詳細については、[「Distruption](https://karpenter.sh/docs/concepts/disruption/#node-level-controls) documentation」を参照してください。

ノードに残っているデーモンセット以外のポッドのみがジョブに関連付けられている場合、Karpenter はジョブのステータスが成功または失敗する限り、それらのノードをターゲットにして終了できます。

### 統合を使用する場合、すべての非 CPU リソースの requests=limits を設定する
<a name="_configure_requestslimits_for_all_non_cpu_resources_when_using_consolidation"></a>

ポッドリソースリクエストとノード上の割り当て可能なリソースの量を比較することで、一般的な作業の統合とスケジューリングを行います。リソースの制限は考慮されません。たとえば、メモリ制限がメモリリクエストより大きいポッドは、リクエストを超えてバーストする可能性があります。同じノード上の複数のポッドが同時にバーストすると、メモリ不足 (OOM) 状態が原因で一部のポッドが終了する可能性があります。統合すると、リクエストのみを考慮してポッドをノードにパックする機能があるため、これが発生する可能性が高くなります。

### LimitRanges を使用してリソースリクエストと制限のデフォルトを設定する
<a name="_use_limitranges_to_configure_defaults_for_resource_requests_and_limits"></a>

Kubernetes はデフォルトのリクエストや制限を設定しないため、コンテナが基盤となるホスト、CPU、メモリからリソースを消費することはバインドされません。Kubernetes スケジューラは、ポッドの合計リクエスト数 (ポッドのコンテナからの合計リクエスト数またはポッドの Init コンテナからの合計リソースのうち高い方) を調べて、ポッドをスケジュールするワーカーノードを決定します。同様に、Karpenter はポッドのリクエストを考慮して、プロビジョニングするインスタンスのタイプを決定します。一部のポッドでリソースリクエストが指定されていない場合に備えて、制限範囲を使用して名前空間に適切なデフォルトを適用できます。

[「名前空間のデフォルトのメモリリクエストと制限を設定する](https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)」を参照してください。

### すべてのワークロードに正確なリソースリクエストを適用する
<a name="_apply_accurate_resource_requests_to_all_workloads"></a>

Karpenter は、ワークロードの要件に関する情報が正確であれば、ワークロードに最適なノードを起動できます。これは、Karpenter の統合機能を使用する場合に特に重要です。

[「すべてのワークロードのリソースリクエスト/制限の設定とサイズ設定」を参照してください。](https://docs.aws.amazon.com/eks/latest/best-practices/data-plane.html#_recommendations)

## CoreDNS レコメンデーション
<a name="_coredns_recommendations"></a>

### CoreDNS の設定を更新して信頼性を維持する
<a name="_update_the_configuration_of_coredns_to_maintain_reliability"></a>

Karpenter が管理するノードに CoreDNS ポッドをデプロイする場合、需要に合わせて新しいノードを迅速に終了/作成するという Karpenter の動的な性質を考慮すると、次のベストプラクティスに従うことをお勧めします。

 [CoreDNS lameduck の期間](https://docs.aws.amazon.com/eks/latest/best-practices/scale-cluster-services.html#_coredns_lameduck_duration) 

 [CoreDNS 準備状況プローブ](https://docs.aws.amazon.com/eks/latest/best-practices/scale-cluster-services.html#_coredns_readiness_probe) 

これにより、DNS クエリが、まだ準備中または終了済みの CoreDNS Pod に転送されないようになります。

## Karpenter の設計図
<a name="_karpenter_blueprints"></a>

Karpenter はアプリケーションファーストのアプローチで のコンピューティングキャパシティを Kubernetes データプレーンにプロビジョニングするため、ワークロードを適切に設定する方法を疑問視する一般的なシナリオがあります。[Karpenter ブループリント](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons)は、ここで説明するベストプラクティスに従った一般的なワークロードシナリオのリストを含むリポジトリです。Karpenter が設定された EKS クラスターを作成し、リポジトリに含まれる各ブループリントをテストするために必要なすべてのリソースがあります。さまざまな設計図を組み合わせて、ワークロードに必要な設計図を最終的に作成できます (複数可）。

## その他のリソース
<a name="_additional_resources"></a>
+  [Karpenter Immersion Day ワークショップ](https://catalog.workshops.aws/karpenter/en-US) 
+  [Karpenter コスト最適化ワークショップ](https://ec2spotworkshops.com/karpenter.html) 
+  [EKS ワークショップ - Karpenter](https://www.eksworkshop.com/docs/autoscaling/compute/karpenter/) 
+  [Karpenter と Cluster Autoscaler](https://youtu.be/FIBc8GkjFU0) 
+  [re:Invent 2023 の Karpenter セッション](https://youtu.be/lkg_9ETHeks) 
+  [チュートリアル: Amazon EC2 スポットと Karpenter を使用して Kubernetes クラスターをより少ない時間実行する](https://community.aws/tutorials/run-kubernetes-clusters-for-less-with-amazon-ec2-spot-and-karpenter#step-6-optional-simulate-spot-interruption) 