Skip to content
Published on

[AWS] Karpenter完全ガイド:Kubernetesノード自動プロビジョニング

Authors

目次

1. Karpenterとは

Karpenterは、AWSが開発したオープンソースのKubernetesノードプロビジョナーです。 従来のCluster AutoscalerがAuto Scaling Group(ASG)を介して間接的にノードを管理するのに対し、 KarpenterはEC2 APIを直接呼び出して、ワークロードに最適化されたノードを数十秒でプロビジョニングします。

主な特徴

  • EC2直接プロビジョニング:ASGを介さずEC2 Fleet APIを直接呼び出し
  • 高速スケーリング:約45〜60秒でノードがオンラインに(CA比3〜4分)
  • インテリジェントなインスタンス選択:ワークロード要件に合った最適なインスタンスタイプを自動選択
  • ビンパッキング最適化:高度なビンパッキングアルゴリズムでクラスタ利用率を最大化
  • 自動統合(Consolidation):未使用ノードの自動削除と低コストノードへの置換
  • ドリフト検知:設定変更時に自動でノードを最新状態に置換

2. なぜKarpenterか:Cluster Autoscalerの限界

Cluster Autoscalerの問題点

+------------------------------------------+
|           Cluster Autoscaler              |
|                                           |
|  Pod Pending                              |
|      |                                    |
|      v                                    |
|  CAがASGにスケールアウトを要求            |
|      |                                    |
|      v                                    |
|  ASGが事前定義のLaunch Templateで         |
|  EC2インスタンスを起動                    |
|      |                                    |
|      v                                    |
|  ノード登録まで3〜5分かかる               |
+------------------------------------------+

Cluster Autoscalerには以下の限界があります:

  1. ASG依存性:事前定義されたNode Groupに縛られ、柔軟性に欠ける
  2. 遅いスケーリング:ASGを経由するため3〜5分のプロビジョニング時間が必要
  3. インスタンスタイプの制限:Node Groupごとに固定されたインスタンスタイプのみ使用可能
  4. 非効率なビンパッキング:Node Group単位でのみスケーリングし、リソースの無駄が発生
  5. 手動管理の負担:多様なワークロードのために複数のNode Groupを手動で管理する必要がある

Karpenterのアプローチ

+------------------------------------------+
|              Karpenter                    |
|                                           |
|  Pod Pending                              |
|      |                                    |
|      v                                    |
|  KarpenterがPodの要件を分析              |
|  (CPU、Memory、GPU、Topology等)          |
|      |                                    |
|      v                                    |
|  最適なインスタンスタイプを自動選択      |
|  (200以上のタイプからコスト最適化)       |
|      |                                    |
|      v                                    |
|  EC2 Fleet APIを直接呼び出し             |
|      |                                    |
|      v                                    |
|  45〜60秒でノードReady                   |
+------------------------------------------+

3. Karpenterアーキテクチャ

全体構造

+----------------------------------------------------------------+
|                     EKS Cluster                                |
|                                                                |
|  +------------------+     +-----------------------------+      |
|  | Karpenter        |     | Kubernetes API Server       |      |
|  | Controller       |---->| (Pod Watch, Node Mgmt)      |      |
|  | (Deployment)     |     +-----------------------------+      |
|  +--------+---------+                                          |
|           |                                                    |
|           |  NodePool + EC2NodeClassを参照                     |
|           |                                                    |
|  +--------v---------+     +-----------------------------+      |
|  | インスタンスタイプ |     | AWS Services                |      |
|  | 選択エンジン      |---->| - EC2 Fleet API             |      |
|  | (コスト/容量最適化)|     | - SSM (AMI Discovery)       |      |
|  +------------------+     | - Pricing API               |      |
|                           | - SQS (Interruption)        |      |
|                           | - EventBridge               |      |
|                           +-----------------------------+      |
+----------------------------------------------------------------+

コアコンポーネント

Karpenterは3つの主要なCRD(Custom Resource Definition)を使用します:

CRDAPIバージョン説明
NodePoolkarpenter.sh/v1ノードプロビジョニングの制約条件を定義
EC2NodeClasskarpenter.k8s.aws/v1AWS固有のインスタンス設定
NodeClaimkarpenter.sh/v1ランタイムに作成されるノード要求オブジェクト

プロビジョニングフロー

1. PodがPending状態で検知される
       |
2. KarpenterがPodのリソース要求、
   nodeSelector、affinity、tolerations等を分析
       |
3. マッチするNodePoolを決定(weight基準の優先順位)
       |
4. EC2NodeClassからAWS設定を参照
   (サブネット、セキュリティグループ、AMI等)
       |
5. 最適なインスタンスタイプを選択
   (コスト、容量、要件に基づく)
       |
6. EC2 Fleet APIでインスタンスを起動
       |
7. NodeClaimオブジェクトを作成し追跡
       |
8. ノード登録完了 -> Podスケジューリング

4. NodePool詳細設定

NodePoolは、Karpenter v1で旧Provisionerを置き換えるコアCRDです。

基本的なNodePool例

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    metadata:
      labels:
        team: platform
        environment: production
    spec:
      requirements:
        # インスタンスカテゴリの制限
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ['c', 'm', 'r']

        # インスタンス世代の制限
        - key: karpenter.k8s.aws/instance-generation
          operator: Gt
          values: ['5']

        # 容量タイプ(on-demandまたはspot)
        - key: karpenter.sh/capacity-type
          operator: In
          values: ['on-demand', 'spot']

        # アベイラビリティゾーン
        - key: topology.kubernetes.io/zone
          operator: In
          values: ['ap-northeast-1a', 'ap-northeast-1c', 'ap-northeast-1d']

        # アーキテクチャ
        - key: kubernetes.io/arch
          operator: In
          values: ['amd64', 'arm64']

      # EC2NodeClass参照
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default

      # ノード有効期限(72時間後に自動置換)
      expireAfter: 72h

  # リソース制限
  limits:
    cpu: '1000'
    memory: 1000Gi

  # 中断(Disruption)ポリシー
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m
    budgets:
      - nodes: '10%'
      - nodes: '0'
        schedule: '0 9 * * MON-FRI'
        duration: 1h

  # NodePool重み(高いほど優先)
  weight: 50

requirementsの主要キー

+---------------------------------------------+--------------------------------------+
| Key                                         | 説明                                 |
+---------------------------------------------+--------------------------------------+
| karpenter.sh/capacity-type                  | on-demandまたはspot                  |
| karpenter.k8s.aws/instance-category         | インスタンスファミリー(c, m, r等)  |
| karpenter.k8s.aws/instance-generation       | インスタンス世代(5, 6, 7等)        |
| karpenter.k8s.aws/instance-size             | インスタンスサイズ(large, xlarge)   |
| karpenter.k8s.aws/instance-gpu-count        | GPU数                                |
| karpenter.k8s.aws/instance-gpu-name         | GPU名(a10g, t4等)                  |
| topology.kubernetes.io/zone                 | アベイラビリティゾーン               |
| kubernetes.io/arch                          | CPUアーキテクチャ                    |
| kubernetes.io/os                            | オペレーティングシステム             |
+---------------------------------------------+--------------------------------------+

マルチNodePool戦略

# 本番ワークロード用(On-Demand専用、高優先度)
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: production
spec:
  template:
    metadata:
      labels:
        workload-type: production
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ['on-demand']
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ['m', 'r']
        - key: karpenter.k8s.aws/instance-generation
          operator: Gt
          values: ['5']
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: production
      expireAfter: 168h
  limits:
    cpu: '500'
    memory: 500Gi
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 5m
  weight: 100
---
# 開発/テスト用(Spot許可、低優先度)
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: development
spec:
  template:
    metadata:
      labels:
        workload-type: development
      annotations:
        dev-team: 'true'
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ['spot', 'on-demand']
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ['c', 'm']
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: development
      expireAfter: 24h
  limits:
    cpu: '200'
    memory: 200Gi
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 30s
  weight: 10

5. EC2NodeClass詳細設定

EC2NodeClassは、AWS固有のインスタンス設定を定義するCRDです。

完全なEC2NodeClass例

apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: default
spec:
  # AMI設定
  amiSelectorTerms:
    - alias: al2023@latest

  # IAMロール
  role: KarpenterNodeRole-my-cluster

  # サブネット選択
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: my-cluster
        network-type: private

  # セキュリティグループ選択
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: my-cluster

  # ブロックデバイスマッピング
  blockDeviceMappings:
    - deviceName: /dev/xvda
      ebs:
        volumeSize: 100Gi
        volumeType: gp3
        iops: 3000
        throughput: 125
        encrypted: true
        deleteOnTermination: true

  # メタデータオプション
  metadataOptions:
    httpEndpoint: enabled
    httpProtocolIPv6: disabled
    httpPutResponseHopLimit: 2
    httpTokens: required

  # タグ
  tags:
    Environment: production
    ManagedBy: karpenter
    Team: platform

  # ユーザーデータ(ブートストラップスクリプト)
  userData: |
    #!/bin/bash
    echo "Karpenter managed node"
    # 追加のブートストラップロジック

AMI選択オプション

# オプション1:エイリアス使用(推奨)
amiSelectorTerms:
  - alias: al2023@latest       # Amazon Linux 2023最新
  # - alias: al2@latest        # Amazon Linux 2
  # - alias: bottlerocket@latest # Bottlerocket

# オプション2:タグベース選択
amiSelectorTerms:
  - tags:
      environment: production
      ami-type: custom-al2023

# オプション3:AMI ID直接指定
amiSelectorTerms:
  - id: ami-0123456789abcdef0

サポートされるAMIファミリー

+-----------------+---------------------------------------------+
| AMIファミリー   | 説明                                        |
+-----------------+---------------------------------------------+
| AL2023          | Amazon Linux 2023(推奨)                   |
| AL2             | Amazon Linux 2                              |
| Bottlerocket    | AWS Bottlerocket(コンテナ専用OS)          |
| Windows2019     | Windows Server 2019                         |
| Windows2022     | Windows Server 2022                         |
| Windows2025     | Windows Server 2025                         |
+-----------------+---------------------------------------------+

6. 統合(Consolidation):コスト最適化の核心

KarpenterのConsolidationは、クラスタコストを自動的に最適化するコア機能です。

Consolidationの動作方式

Consolidationタイプ:
+------------------------------------------------------------------+
|                                                                  |
|  1. 削除(Delete)Consolidation                                  |
|     - ノードの全Podが他のノードで実行可能な場合                  |
|     - 該当ノードを安全に削除                                     |
|                                                                  |
|  2. 置換(Replace)Consolidation                                 |
|     - 現在のノードをより小さく安価なインスタンスに置換可能な場合 |
|     - 新ノードプロビジョニング -> Pod移行 -> 旧ノード削除        |
|                                                                  |
+------------------------------------------------------------------+

Consolidationポリシー設定

# ポリシー1:空ノードのみ統合
disruption:
  consolidationPolicy: WhenEmpty
  consolidateAfter: 30s

# ポリシー2:空ノード + 低活用ノード統合(推奨)
disruption:
  consolidationPolicy: WhenEmptyOrUnderutilized
  consolidateAfter: 1m

Disruption Budgetで速度を制御

disruption:
  consolidationPolicy: WhenEmptyOrUnderutilized
  consolidateAfter: 1m
  budgets:
    # 全ノードの10%までのみ同時中断を許可
    - nodes: '10%'

    # 業務時間中は中断をブロック
    - nodes: '0'
      schedule: '0 9 * * MON-FRI'
      duration: 8h

    # 特定の理由に対してのみバジェットを適用(v1.0+)
    - nodes: '5%'
      reasons:
        - 'Underutilized'

Spot-to-Spot Consolidation

Spotインスタンス間の統合は、最低15個以上のインスタンスタイプが設定されている必要があります。

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: spot-optimized
spec:
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ['spot']
        # 多様なインスタンスタイプでSpot-to-Spot統合を有効化
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ['c', 'm', 'r']
        - key: karpenter.k8s.aws/instance-generation
          operator: Gt
          values: ['4']
        - key: karpenter.k8s.aws/instance-size
          operator: In
          values: ['large', 'xlarge', '2xlarge', '4xlarge']

7. ドリフト検知(Drift Detection)

ドリフト検知は、NodePoolやEC2NodeClassの設定が変更された際に、既存ノードが最新設定と一致しないことを検知し、自動的に置換する機能です。

ドリフトが検知されるケース

+---------------------------------------------------+
| ドリフト検知シナリオ                              |
+---------------------------------------------------+
| - AMIが更新された場合                             |
| - NodePoolのrequirementsが変更された場合          |
| - EC2NodeClassのセキュリティグループが変更された場合 |
| - EC2NodeClassのサブネットが変更された場合        |
| - ブロックデバイス設定が変更された場合            |
| - メタデータオプションが変更された場合            |
| - タグが変更された場合                            |
+---------------------------------------------------+

ドリフト置換プロセス

1. KarpenterがNodeClaimと現在のNodePool/EC2NodeClassを比較
       |
2. 差異を発見した場合、NodeClaimにDrifted状態をマーク
       |
3. Disruption Budgetを確認
       |
4. 新ノードをプロビジョニング(最新設定を適用)
       |
5. 既存ノードのPodを安全にdrain
       |
6. 既存ノードを終了

8. 中断処理(Interruption Handling)

Karpenterは、さまざまなEC2中断イベントを自動的に処理します。

サポートされる中断タイプ

+-----------------------------+------------------------------------------+
| 中断タイプ                  | 説明                                     |
+-----------------------------+------------------------------------------+
| Spot Interruption           | 2分前の警告でSpot回収を通知              |
| Rebalance Recommendation    | 中断リスク増加時の事前通知               |
| Scheduled Maintenance       | AWSの予定メンテナンスイベント            |
| Instance State Change       | インスタンス状態変更(stopping, stopped)|
+-----------------------------+------------------------------------------+

SQSベースの中断処理アーキテクチャ

+-------------------+     +-------------------+     +------------------+
| EC2 Spot          |     | Amazon            |     | Amazon           |
| Interruption      |---->| EventBridge       |---->| SQS Queue        |
| Notice            |     | Rules             |     |                  |
+-------------------+     +-------------------+     +--------+---------+
                                                             |
+-------------------+     +-------------------+              |
| EC2 Rebalance     |---->| EventBridge       |----+         |
| Recommendation    |     |                   |    |         |
+-------------------+     +-------------------+    |         |
                                                   v         v
                                              +----+---------+----+
                                              | Karpenter         |
                                              | Controller        |
                                              |                   |
                                              | 1. イベント受信   |
                                              | 2. ノードCordon   |
                                              | 3. Pod Drain      |
                                              | 4. 新ノード起動   |
                                              | 5. 既存ノード終了 |
                                              +-------------------+

中断処理の設定

Helmインストール時にSQSキュー名を指定します:

helm install karpenter oci://public.ecr.aws/karpenter/karpenter \
  --version "1.0.0" \
  --namespace karpenter \
  --create-namespace \
  --set "settings.clusterName=my-cluster" \
  --set "settings.interruptionQueue=my-cluster-karpenter" \
  --set controller.resources.requests.cpu=1 \
  --set controller.resources.requests.memory=1Gi \
  --set controller.resources.limits.cpu=1 \
  --set controller.resources.limits.memory=1Gi

9. Spotインスタンスのベストプラクティス

多様なインスタンスタイプの設定

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: spot-diverse
spec:
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ['spot']
        # 多様なインスタンスファミリーでSpot可用性を確保
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ['c', 'm', 'r']
        # 複数世代を許可
        - key: karpenter.k8s.aws/instance-generation
          operator: In
          values: ['5', '6', '7']
        # さまざまなサイズを許可
        - key: karpenter.k8s.aws/instance-size
          operator: In
          values: ['large', 'xlarge', '2xlarge', '4xlarge']
        # 複数のアベイラビリティゾーン
        - key: topology.kubernetes.io/zone
          operator: In
          values: ['ap-northeast-1a', 'ap-northeast-1c', 'ap-northeast-1d']
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default

Spot + On-Demand混合戦略

# Spot優先NodePool(高い重み)
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: spot-first
spec:
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ['spot']
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
  weight: 100
  limits:
    cpu: '500'
---
# On-Demandフォールバック NodePool(低い重み)
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: on-demand-fallback
spec:
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ['on-demand']
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
  weight: 1
  limits:
    cpu: '200'

Spot使用時の注意事項

  • 多様なインスタンスタイプを許可:最低15個以上のインスタンスタイプを許可してSpot可用性を最大化
  • 複数のアベイラビリティゾーンを使用:単一AZに依存せず複数AZでSpot容量を確保
  • PDB(Pod Disruption Budget)の設定:重要なワークロードにPDBを設定して最小可用性を保証
  • グレースフルシャットダウンの処理:terminationGracePeriodSecondsを適切に設定

10. Helmを使ったKarpenterのインストール

前提条件

# 環境変数の設定
export KARPENTER_NAMESPACE="karpenter"
export KARPENTER_VERSION="1.0.0"
export CLUSTER_NAME="my-eks-cluster"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export TEMPOUT="$(mktemp)"

IAMロールの作成

# Karpenterコントローラーロールの作成
aws iam create-role \
  --role-name "KarpenterControllerRole-my-cluster" \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::oidc-provider/oidc.eks.REGION.amazonaws.com/id/EXAMPLE"
      },
      "Action": "sts:AssumeRoleWithWebIdentity"
    }]
  }'

# Karpenterノードロールの作成
aws iam create-role \
  --role-name "KarpenterNodeRole-my-cluster" \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }]
  }'

Helmインストール

# OCIレジストリからインストール
helm install karpenter oci://public.ecr.aws/karpenter/karpenter \
  --version "1.0.0" \
  --namespace karpenter \
  --create-namespace \
  --set "settings.clusterName=my-cluster" \
  --set "settings.interruptionQueue=my-cluster-karpenter" \
  --set "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn=arn:aws:iam::123456789012:role/KarpenterControllerRole-my-cluster" \
  --set controller.resources.requests.cpu=1 \
  --set controller.resources.requests.memory=1Gi \
  --set controller.resources.limits.cpu=1 \
  --set controller.resources.limits.memory=1Gi \
  --wait

インストール確認

# Karpenter Podの状態確認
kubectl get pods -n karpenter

# CRDの確認
kubectl get crd | grep karpenter

# ログの確認
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter -f

11. 完全なデプロイメント例

フル構成(NodePool + EC2NodeClass)

apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: production
spec:
  amiSelectorTerms:
    - alias: al2023@latest
  role: KarpenterNodeRole-my-cluster
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: my-cluster
        network-type: private
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: my-cluster
  blockDeviceMappings:
    - deviceName: /dev/xvda
      ebs:
        volumeSize: 100Gi
        volumeType: gp3
        iops: 3000
        throughput: 125
        encrypted: true
        deleteOnTermination: true
  metadataOptions:
    httpEndpoint: enabled
    httpPutResponseHopLimit: 2
    httpTokens: required
  tags:
    Environment: production
    ManagedBy: karpenter
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: production
spec:
  template:
    metadata:
      labels:
        environment: production
        managed-by: karpenter
    spec:
      requirements:
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ['c', 'm', 'r']
        - key: karpenter.k8s.aws/instance-generation
          operator: Gt
          values: ['5']
        - key: karpenter.sh/capacity-type
          operator: In
          values: ['on-demand']
        - key: topology.kubernetes.io/zone
          operator: In
          values: ['ap-northeast-1a', 'ap-northeast-1c', 'ap-northeast-1d']
        - key: kubernetes.io/arch
          operator: In
          values: ['amd64']
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: production
      expireAfter: 168h
  limits:
    cpu: '1000'
    memory: 2000Gi
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 2m
    budgets:
      - nodes: '10%'
      - nodes: '0'
        schedule: '0 2 * * *'
        duration: 1h
  weight: 100

テストワークロードのデプロイ

apiVersion: apps/v1
kind: Deployment
metadata:
  name: inflate
  namespace: default
spec:
  replicas: 0
  selector:
    matchLabels:
      app: inflate
  template:
    metadata:
      labels:
        app: inflate
    spec:
      containers:
        - name: inflate
          image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
          resources:
            requests:
              cpu: '1'
              memory: 1Gi
# スケールアップしてKarpenterプロビジョニングをトリガー
kubectl scale deployment inflate --replicas=10

# ノードプロビジョニングを確認
kubectl get nodes -w

# NodeClaimの状態を確認
kubectl get nodeclaims

# スケールダウンしてConsolidationを確認
kubectl scale deployment inflate --replicas=0

12. Karpenter vs Cluster Autoscaler比較表

+-----------------------------+----------------------------+----------------------------+
| 項目                        | Karpenter                  | Cluster Autoscaler         |
+-----------------------------+----------------------------+----------------------------+
| プロビジョニング方式        | EC2 API直接呼び出し        | ASG経由の間接呼び出し      |
| プロビジョニング速度        | 45〜60秒                   | 3〜5分                     |
| インスタンス選択            | 自動最適化(200+タイプ)   | Node Group固定タイプ       |
| ビンパッキング              | Pod単位の最適化            | Node Group単位             |
| Consolidation               | 内蔵(自動)               | 限定的(スケールダウンのみ)|
| ドリフト検知                | 自動                       | 未サポート                 |
| Spotインスタンス            | ネイティブ対応、自動多角化 | ASG Mixed Instances        |
| Spot中断処理                | SQSベースの自動処理        | 別途ツールが必要           |
| マルチアーキテクチャ        | AMD64 + ARM64自動選択      | 別途Node Groupが必要       |
| 設定の複雑さ                | NodePool + EC2NodeClass    | ASG + Launch Template      |
| マルチクラウド              | AWS専用(コミュニティ拡張)| 公式マルチクラウド         |
| コスト削減効果              | 25〜40%(ビンパック+Spot) | 10〜20%                    |
| K8s公式プロジェクト         | いいえ(AWS主導)          | はい(SIG Autoscaling)    |
+-----------------------------+----------------------------+----------------------------+

13. よくある問題とトラブルシューティング

PodがPending状態のままの場合

# NodePoolの要件を確認
kubectl describe nodepool default

# Karpenterログでプロビジョニング失敗の原因を確認
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter | grep -i "error\|failed"

# Podイベントを確認
kubectl describe pod my-pod-name

一般的な原因と解決方法

  1. サブネットまたはセキュリティグループのタグ未設定:EC2NodeClassのselectorタグが実際のAWSリソースに適用されているか確認
  2. IAM権限不足:Karpenterコントローラーロールに必要なEC2、IAM、SSM権限があるか確認
  3. リソース制限超過:NodePoolのlimits設定が現在の使用量を超えていないか確認
  4. インスタンスタイプの可用性:特定のAZで該当インスタンスタイプの容量が不足している場合がある

14. まとめ

Karpenterは、Kubernetesノードプロビジョニングのパラダイムを変革しています。 ASGベースの静的なノード管理から脱却し、ワークロード中心の動的なインフラプロビジョニングを実現しました。

導入推奨シナリオ

  • 多様なインスタンスタイプが必要なワークロード
  • Spotインスタンスを積極的に活用したい場合
  • 高速スケーリングが重要なイベント型ワークロード
  • コスト最適化がコア目標のクラスタ
  • GPU/MLワークロードを含む環境

注意事項

  • AWS EKS専用のため、マルチクラウド環境ではCluster Autoscalerの併用を検討
  • v1.0+安定バージョンの使用を推奨
  • SQSキュー設定でSpot中断処理を必ず有効化
  • NodePoolのlimitsを適切に設定してコスト暴走を防止