Skip to content

Karpenter

サポート対象バージョン: Karpenter 1.6 - 1.14, Kubernetes 1.29+ (as of v1.14) 最終更新: July 11, 2026

目次

はじめに

Karpenter は、Kubernetes cluster の node provisioning を自動化するオープンソースの cluster autoscaler です。Karpenter は workload の要件に基づいて適切な compute resource を動的にプロビジョニングし、アプリケーションの可用性を確保しながら cluster 効率を最適化します。

Karpenter の主な利点

  1. 高速なスケーリング: workload 要件に基づき、数秒以内に node をプロビジョニング
  2. コスト最適化: workload に最も適した instance type を選択
  3. シンプルな設定: 宣言的 API による簡単な設定
  4. Workload 中心の設計: Pod 要件に基づく node provisioning
  5. Cloud 統合: cloud provider の機能を活用
  6. 効率的な Bin Packing: resource utilization を最適化
  7. 柔軟な Node 管理: node lifecycle 管理と統合された interruption handling

既存の Autoscaler との比較

FeatureKarpenterCluster AutoscalerCloud Provider Managed Node Groups
Scaling SpeedVery Fast (seconds)Medium (minutes)Slow (minutes)
Instance Type SelectionDynamicNode group-basedNode group-based
Bin Packing EfficiencyHighMediumLow
Configuration ComplexityLowMediumLow
Cloud IntegrationNativeLimitedNative
Node Group ManagementNot RequiredRequiredRequired
Interruption HandlingIntegratedLimitedLimited

注記: Karpenter ではなく従来の EKS Managed Node Groups と Cluster Autoscaler を使い続ける場合、EC2 Auto Scaling Warm Pools(2026 年 4 月から利用可能)を使うことで、事前に初期化済みの instance を standby 状態に維持し、cold start なしの scale-out を実現できます。Stopped state(低コスト)または Running state(高速な移行)を選択でき、Cluster Autoscaler と自動的に統合されます。ただし、これは Managed Node Group の機能であり、Karpenter が使用するものではありません。

アーキテクチャ

Karpenter は Kubernetes controller として動作し、スケジュール不能な Pod を検出して適切な node をプロビジョニングします。

Karpenter のワークフロー

次の図は、Karpenter が EKS cluster でどのように動作するかを示しています。

主要コンポーネント

  1. Karpenter Controller: スケジュール不能な Pod を検出し、node provisioning を管理します
  2. Karpenter Webhook: Karpenter resource を検証します
  3. Provisioner CRD: node provisioning policy を定義します
  4. NodeTemplate CRD: プロビジョニングされる node の設定を定義します
  5. Cloud Provider Integration: cloud provider API と統合し、compute resource を管理します

動作の仕組み

  1. Karpenter Controller がスケジュール不能な Pod を検出します
  2. Pod 要件(resource、node selector、toleration など)を分析します
  3. provisioner と node template の設定に基づいて適切な node type を決定します
  4. cloud provider API を呼び出して node をプロビジョニングします
  5. node が cluster に参加すると Pod をスケジュールします
  6. node が不要になった場合、統合された interruption handling によって node を削除します

インストールと設定

前提条件

  • Kubernetes cluster (v1.19 以上)
  • kubectl 設定済み
  • Cloud provider の credentials と permissions
  • Helm (任意)

AWS EKS へのインストール

1. IAM Role と Policy のセットアップ

bash
# IRSA setup using eksctl
eksctl create iamserviceaccount \
  --cluster=my-cluster \
  --name=karpenter \
  --namespace=karpenter \
  --attach-policy-arn=arn:aws:iam::aws:policy/AmazonEKSClusterPolicy \
  --attach-policy-arn=arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
  --approve

# Create instance profile
aws iam create-instance-profile --instance-profile-name KarpenterNodeInstanceProfile

# Create node role
aws iam create-role --role-name KarpenterNodeRole --assume-role-policy-document file://node-trust-policy.json

# Attach policies to node role
aws iam attach-role-policy --role-name KarpenterNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
aws iam attach-role-policy --role-name KarpenterNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
aws iam attach-role-policy --role-name KarpenterNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
aws iam attach-role-policy --role-name KarpenterNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

# Add role to instance profile
aws iam add-role-to-instance-profile --instance-profile-name KarpenterNodeInstanceProfile --role-name KarpenterNodeRole

2. Helm を使用したインストール

bash
# Add Helm repository
helm repo add karpenter https://charts.karpenter.sh
helm repo update

# Install Karpenter
helm install karpenter karpenter/karpenter \
  --namespace karpenter \
  --create-namespace \
  --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::${ACCOUNT_ID}:role/KarpenterControllerRole \
  --set clusterName=${CLUSTER_NAME} \
  --set clusterEndpoint=${CLUSTER_ENDPOINT} \
  --set aws.defaultInstanceProfile=KarpenterNodeInstanceProfile

3. インストールの確認

bash
kubectl get pods -n karpenter

想定される出力:

NAME                         READY   STATUS    RESTARTS   AGE
karpenter-6f4f46d855-5lqx7   1/1     Running   0          1m

基本的な Provisioner 設定

yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s
  limits:
    cpu: 1000
    memory: 1000Gi
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand"]
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["m5.large", "m5.xlarge", "m5.2xlarge"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
---
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: default
spec:
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "true"
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "true"
  tags:
    karpenter.sh/discovery: "true"
  blockDeviceMappings:
    - deviceName: /dev/xvda
      ebs:
        volumeSize: 100Gi
        volumeType: gp3
        deleteOnTermination: true

NodePool

NodePool は、Karpenter が node をどのようにプロビジョニングするかを定義する Kubernetes custom resource です。以前の Provisioner を置き換えるものです。

基本的な NodePool 設定

yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  # Node requirements
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand"]
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["m5.large", "m5.xlarge", "m5.2xlarge"]

  # Resource limits
  limits:
    cpu: 1000
    memory: 1000Gi

  # Node class reference
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default

  # Node expiration settings
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s
    expireAfter: 720h  # 30 days

  # Taints and labels
  template:
    spec:
      taints:
        - key: example.com/special-taint
          value: "true"
          effect: NoSchedule
      labels:
        environment: production
        app: web

  # Startup template
  template:
    spec:
      startupTaints:
        - key: node.kubernetes.io/not-ready
          effect: NoSchedule

Requirements 設定

Requirements は、Karpenter がプロビジョニングする node の特性を定義します。

yaml
template:
  spec:
    requirements:
      # Capacity type (on-demand or spot)
      - key: karpenter.sh/capacity-type
        operator: In
        values: ["on-demand", "spot"]

      # Architecture
      - key: kubernetes.io/arch
        operator: In
        values: ["amd64", "arm64"]

      # Instance types
      - key: node.kubernetes.io/instance-type
        operator: In
        values: ["m5.large", "m5.xlarge", "c5.large"]

      # Availability zones
      - key: topology.kubernetes.io/zone
        operator: In
        values: ["us-west-2a", "us-west-2b", "us-west-2c"]

      # Operating system
      - key: kubernetes.io/os
        operator: In
        values: ["linux"]

Limits 設定

Limits は、Karpenter がプロビジョニングできる resource の最大量を定義します。

yaml
limits:
  cpu: 1000
  memory: 1000Gi
  nvidia.com/gpu: 10

Dynamic Resource Allocation (DRA) サポート (v1.13)

Karpenter v1.13(2026 年 6 月リリース)から、Karpenter は Kubernetes Dynamic Resource Allocation (DRA) に基づく device allocation tracking をサポートします。Karpenter は GPU や専用 accelerator などの claim-based resource を認識し、provisioning decision に組み込めるようになりました。これにより、nvidia.com/gpu のような extended resource だけでなく、DRA の ResourceClaim/DeviceClass object を使用する AI/HPC workload に対しても正確なスケーリングが可能になります。DRA-based tracking には Kubernetes 1.29 以降が必要です。

Node 有効期限設定

Node expiration settings は、Karpenter が node を削除するタイミングを定義します。

yaml
disruption:
  # Consolidate (remove) when node is empty
  consolidationPolicy: WhenEmpty

  # Time until consolidation (removal) after node becomes empty
  consolidateAfter: 30s

  # Maximum time before removing node after creation
  expireAfter: 720h  # 30 days

NodeReadinessController による Initialization Taint の自動無視 (v1.13)

Karpenter v1.13 で追加された NodeReadinessController は、node の初期化中に適用されるものなど readiness 関連の taint を自動的に無視し、不要な scheduling block を減らします。これにより、以前は startupTaints による手動対応が必要だった initialization-delay の問題が緩和され、新しい node が Ready になるまでの scheduling stability と provisioning reliability が向上します。

2026 年 7 月アップデート: v1.14 リリース

2026 年 7 月 11 日にリリースされた Karpenter v1.14 には、次の内容が含まれます。

  • CapacityBuffers API support: 急激な scale-out スパイクを吸収するための余裕 capacity を宣言的に予約
  • Preview instance type support: まだ一般提供されていない instance type を provisioning に選択可能
  • Nitro Enclaves support: confidential-computing workload に有用な EnclaveOptions.Enabled を launch template で設定可能
  • バグ修正: secondary ENI の primary IP の計上、Zonal Shift cache の hydration 確保、AWS SDK client timeout の operator config への接続など

詳細は v1.14.0 release notes を参照してください。

Node Classes

Node class は、Karpenter がプロビジョニングする node の設定を定義します。AWS では EC2NodeClass CRD を使用します。

AWS EC2NodeClass 設定

yaml
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: default
spec:
  # Subnet selection
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "true"

  # Security group selection
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "true"

  # Instance tags
  tags:
    karpenter.sh/discovery: "true"
    environment: production

  # Block device mappings
  blockDeviceMappings:
    - deviceName: /dev/xvda
      ebs:
        volumeSize: 100Gi
        volumeType: gp3
        deleteOnTermination: true
        encrypted: true

  # Detailed instance configuration
  role: KarpenterNodeRole
  amiFamily: AL2
  userData: |
    #!/bin/bash
    echo "Hello from Karpenter node!"

  # Metadata options
  metadataOptions:
    httpEndpoint: enabled
    httpProtocolIPv6: disabled
    httpPutResponseHopLimit: 2
    httpTokens: required

Subnet と Security Group の選択

Subnet と security group は label selector を使用して選択できます。

yaml
# Subnet selection
subnetSelector:
  karpenter.sh/discovery: "true"
  Name: "private-*"

# Security group selection
securityGroupSelector:
  karpenter.sh/discovery: "true"
  aws:eks:cluster-name: "my-cluster"

AMI 設定

Karpenter はさまざまな AMI family をサポートしています。

yaml
# Amazon Linux 2
amiFamily: AL2

# Bottlerocket
amiFamily: Bottlerocket

# Ubuntu
amiFamily: Ubuntu

# Custom AMI
amiSelector:
  aws:ec2:image:id: "ami-0123456789abcdef0"

Block Device 設定

node の storage 設定を定義できます。

yaml
blockDeviceMappings:
  # Root volume
  - deviceName: /dev/xvda
    ebs:
      volumeSize: 100Gi
      volumeType: gp3
      iops: 3000
      throughput: 125
      deleteOnTermination: true
      encrypted: true
      kmsKeyID: "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"

  # Additional volume
  - deviceName: /dev/xvdb
    ebs:
      volumeSize: 500Gi
      volumeType: gp3
      deleteOnTermination: true

User Data 設定

node 起動時に実行する user data script を定義できます。

yaml
userData: |
  #!/bin/bash
  echo "Hello from Karpenter node!"

  # System configuration
  sysctl -w vm.max_map_count=262144

  # Package installation
  yum update -y
  yum install -y amazon-cloudwatch-agent

  # Start CloudWatch agent
  systemctl enable amazon-cloudwatch-agent
  systemctl start amazon-cloudwatch-agent

Node Consolidation プロセス

次の図は Karpenter の node consolidation process を示しています。この機能は cluster 効率の最適化とコスト削減に重要です。

中断処理

Karpenter は workload の可用性を確保するため、node interruption を自動的に処理します。

統合された Interruption Handling

Karpenter は次の interruption event を処理します。

  1. Spot Instance Interruptions: AWS Spot instance の interruption notification を処理します
  2. Node Expiration: TTL に基づく node replacement
  3. Scale Down: 不要になった node を削除します
  4. Node Consolidation: より効率的な node configuration に統合します

Interruption Handling 設定

yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  # Other configuration...

  # Node expiration settings
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s
    expireAfter: 720h  # 30 days

Draining 設定

Karpenter は node を削除する前に Pod を安全に drain します。

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: karpenter-global-settings
  namespace: karpenter
data:
  aws:
    enablePodENI: "true"
  batchMaxDuration: "10s"
  batchIdleDuration: "1s"
  featureGates:
    driftEnabled: "true"
  nodePool:
    disruptionBudget:
      maxUnavailablePercentage: "30"
    disruption:
      consolidationPolicy: WhenEmpty
      consolidateAfter: 30s
      expireAfter: 720h

PDB (PodDisruptionBudget) 統合

Karpenter はアプリケーションの可用性を確保するために PDB を尊重します。

yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: app-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: my-app

統合

Karpenter はさまざまな Kubernetes service および cloud service と統合されます。

Kubernetes 統合

1. Pod Topology Spread Constraints

Karpenter は node をプロビジョニングする際に Pod Topology Spread Constraints を考慮します。

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  replicas: 10
  template:
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: web-server

2. Pod Affinity/Anti-Affinity

Karpenter は Pod Affinity と Anti-Affinity rule を考慮します。

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  replicas: 10
  template:
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - web-server
              topologyKey: "kubernetes.io/hostname"

3. Taints and Tolerations

Karpenter は node をプロビジョニングする際に taint と toleration を考慮します。

yaml
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: gpu
spec:
  requirements:
    - key: node.kubernetes.io/instance-type
      operator: In
      values: ["g4dn.xlarge", "g4dn.2xlarge"]
  taints:
    - key: nvidia.com/gpu
      value: "true"
      effect: NoSchedule
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gpu-app
spec:
  replicas: 3
  template:
    spec:
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      nodeSelector:
        karpenter.sh/provisioner-name: gpu

AWS 統合

1. EC2 Spot Instances

Karpenter はコスト最適化のために EC2 Spot instance をサポートしています。

yaml
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: spot
spec:
  requirements:
    - key: karpenter.sh/capacity-type
      operator: In
      values: ["spot"]
  providerRef:
    name: spot
---
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
  name: spot
spec:
  subnetSelector:
    karpenter.sh/discovery: "true"
  securityGroupSelector:
    karpenter.sh/discovery: "true"

2. EC2 Instance Profiles

Karpenter は node に IAM 権限を付与するために EC2 instance profile を使用します。

yaml
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
  name: default
spec:
  instanceProfile: KarpenterNodeInstanceProfile

3. Launch Templates

Karpenter は EC2 launch template をサポートしています。

yaml
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
  name: custom-launch-template
spec:
  launchTemplate:
    name: my-launch-template
    version: "1"

Amazon EKS との統合

Karpenter は Amazon EKS とシームレスに統合し、cluster autoscaling を提供します。

EKS Cluster の準備

1. Cluster Tag セットアップ

Karpenter が cluster resource を識別できるように tag を設定します。

bash
# Set cluster name
CLUSTER_NAME="my-cluster"

# VPC tag setup
aws ec2 create-tags \
  --resources $(aws eks describe-cluster \
    --name ${CLUSTER_NAME} \
    --query "cluster.resourcesVpcConfig.vpcId" \
    --output text) \
  --tags Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}

# Subnet tag setup
for SUBNET in $(aws eks describe-cluster \
  --name ${CLUSTER_NAME} \
  --query "cluster.resourcesVpcConfig.subnetIds[]" \
  --output text); do
  aws ec2 create-tags \
    --resources ${SUBNET} \
    --tags Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}
done

# Security group tag setup
aws ec2 create-tags \
  --resources $(aws eks describe-cluster \
    --name ${CLUSTER_NAME} \
    --query "cluster.resourcesVpcConfig.clusterSecurityGroupId" \
    --output text) \
  --tags Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}

2. IAM Role セットアップ

Karpenter controller と node に必要な IAM role を設定します。

bash
# Create controller role
cat <<EOF > controller-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${OIDC_PROVIDER}:sub": "system:serviceaccount:karpenter:karpenter",
          "${OIDC_PROVIDER}:aud": "sts.amazonaws.com"
        }
      }
    }
  ]
}
EOF

aws iam create-role \
  --role-name KarpenterControllerRole-${CLUSTER_NAME} \
  --assume-role-policy-document file://controller-trust-policy.json

# Create controller policy
cat <<EOF > controller-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateLaunchTemplate",
        "ec2:CreateFleet",
        "ec2:RunInstances",
        "ec2:CreateTags",
        "ec2:TerminateInstances",
        "ec2:DescribeLaunchTemplates",
        "ec2:DescribeInstances",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSubnets",
        "ec2:DescribeInstanceTypes",
        "ec2:DescribeInstanceTypeOfferings",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeSpotPriceHistory",
        "pricing:GetProducts",
        "ssm:GetParameter"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resources": "arn:aws:iam::${ACCOUNT_ID}:role/KarpenterNodeRole-${CLUSTER_NAME}",
      "Condition": {
        "StringEquals": {
          "iam:PassedToService": "ec2.amazonaws.com"
        }
      }
    }
  ]
}
EOF

aws iam put-role-policy \
  --role-name KarpenterControllerRole-${CLUSTER_NAME} \
  --policy-name KarpenterControllerPolicy-${CLUSTER_NAME} \
  --policy-document file://controller-policy.json

EKS Cluster への Karpenter インストール

bash
# Installation using Helm
helm install karpenter karpenter/karpenter \
  --namespace karpenter \
  --create-namespace \
  --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::${ACCOUNT_ID}:role/KarpenterControllerRole-${CLUSTER_NAME} \
  --set clusterName=${CLUSTER_NAME} \
  --set clusterEndpoint=$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output text) \
  --set aws.defaultInstanceProfile=KarpenterNodeInstanceProfile-${CLUSTER_NAME}

EKS Managed Node Groups との併用

Karpenter は EKS Managed Node Groups と併用できます。

yaml
# Provisioner for EKS Managed Node Groups
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: managed-ng
spec:
  requirements:
    - key: karpenter.sh/capacity-type
      operator: In
      values: ["on-demand"]
    - key: node.kubernetes.io/instance-type
      operator: In
      values: ["m5.large", "m5.xlarge"]
  labels:
    managed-by: karpenter
  taints:
    - key: managed-by
      value: karpenter
      effect: NoSchedule
  providerRef:
    name: managed-ng
  ttlSecondsAfterEmpty: 30
---
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
  name: managed-ng
spec:
  subnetSelector:
    karpenter.sh/discovery: "${CLUSTER_NAME}"
  securityGroupSelector:
    karpenter.sh/discovery: "${CLUSTER_NAME}"
  tags:
    karpenter.sh/discovery: "${CLUSTER_NAME}"

EKS Fargate との併用

Karpenter は EKS Fargate と併用して hybrid cluster を構成できます。

yaml
# Create Fargate profile
aws eks create-fargate-profile \
  --cluster-name ${CLUSTER_NAME} \
  --fargate-profile-name fp-default \
  --pod-execution-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKSFargatePodExecutionRole \
  --selectors namespace=default,namespace=kube-system

# Karpenter NodePool configuration
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: ec2
spec:
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: ec2
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s
---
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: ec2
spec:
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "${CLUSTER_NAME}"
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "${CLUSTER_NAME}"

AZ 障害対応: Amazon ARC Zonal Shift 統合 (2026 年 5 月)

Karpenter は Amazon ARC (Application Recovery Controller) の Zonal Shift をサポートしています。Availability Zone (AZ) に障害が発生すると、Karpenter はその AZ での新しい node のプロビジョニングを自動的に停止し、代わりに正常な AZ へ workload をスケジュールします。AWS が AZ の health を自動的に検出し、traffic shifting と recovery を処理する Zonal Autoshift もサポートされています。

障害が検出されると、Karpenter は voluntary disruption(consolidation、drift handling など)も自動的に一時停止します。これにより、outage 中に不要な node replacement によって cluster がさらに不安定化することを防ぎます。これは既存の EKS ARC resource を直接使用します。custom resource は不要で、ENABLE_ZONAL_SHIFT option により有効化されます。

EKS コスト最適化

Karpenter を使用して EKS cluster のコストを最適化できます。

1. Spot Instances の使用

yaml
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: spot
spec:
  requirements:
    - key: karpenter.sh/capacity-type
      operator: In
      values: ["spot"]
    - key: kubernetes.io/arch
      operator: In
      values: ["amd64", "arm64"]
  providerRef:
    name: spot
  ttlSecondsAfterEmpty: 30
---
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
  name: spot
spec:
  subnetSelector:
    karpenter.sh/discovery: "${CLUSTER_NAME}"
  securityGroupSelector:
    karpenter.sh/discovery: "${CLUSTER_NAME}"

2. 多様な Instance Type の使用

yaml
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: flexible
spec:
  requirements:
    - key: karpenter.sh/capacity-type
      operator: In
      values: ["on-demand", "spot"]
    - key: kubernetes.io/arch
      operator: In
      values: ["amd64", "arm64"]
    - key: node.kubernetes.io/instance-type
      operator: In
      values: [
        "m5.large", "m5.xlarge", "m5.2xlarge",
        "m6g.large", "m6g.xlarge", "m6g.2xlarge",
        "c5.large", "c5.xlarge", "c5.2xlarge",
        "c6g.large", "c6g.xlarge", "c6g.2xlarge",
        "r5.large", "r5.xlarge", "r5.2xlarge",
        "r6g.large", "r6g.xlarge", "r6g.2xlarge"
      ]
  providerRef:
    name: flexible
  ttlSecondsAfterEmpty: 30

3. Node Consolidation の有効化

yaml
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: default
spec:
  consolidation:
    enabled: true
  # Other configuration...

ベストプラクティス

パフォーマンス最適化

  1. Select Appropriate Instance Types: workload に適した instance type を選択します
  2. Allow Diverse Instance Types: 可用性とコスト最適化のためにさまざまな instance type を許可します
  3. Set Appropriate TTL: workload pattern に合った TTL を設定します
  4. Enable Node Consolidation: resource utilization を最適化するために node consolidation を有効化します
yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: optimized
spec:
  # Allow diverse instance types
  template:
    spec:
      requirements:
        - key: node.kubernetes.io/instance-type
          operator: In
          values: [
            "m5.large", "m5.xlarge", "m5.2xlarge",
            "c5.large", "c5.xlarge", "c5.2xlarge",
            "r5.large", "r5.xlarge", "r5.2xlarge"
          ]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: optimized

  # Set appropriate TTL
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s
    expireAfter: 720h  # 30 days

コスト最適化

  1. Utilize Spot Instances: コスト削減のために Spot instance を使用します
  2. Select Appropriate Instance Sizes: workload に適した instance size を選択します
  3. Utilize Zero Scaling: activity がない場合は node 数を 0 に減らします
  4. Set Node Expiration: 定期的な node replacement によって最新の instance type を活用します
yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: cost-optimized
spec:
  # Use Spot instances
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: cost-optimized

  # Zero scaling and node expiration settings
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s
    expireAfter: 168h  # 7 days

可用性の向上

  1. Use Multiple Availability Zones: 複数の availability zone に node をデプロイします
  2. Mix On-demand and Spot Instances: 可用性とコストのバランスを取ります
  3. Set Appropriate PDBs: アプリケーションの可用性を確保します
  4. Optimize Interruption Handling: node interruption 中の workload 可用性を確保します
yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: high-availability
spec:
  # Use multiple availability zones
  template:
    spec:
      requirements:
        - key: topology.kubernetes.io/zone
          operator: In
          values: ["us-west-2a", "us-west-2b", "us-west-2c"]
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand", "spot"]
      nodeClassRef:
        name: high-availability

  # Optimize interruption handling
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 60s
  ttlSecondsUntilExpired: 2592000  # 30 days

  # Node consolidation settings
  consolidation:
    enabled: true

トラブルシューティング

よくある問題

1. Node Provisioning Failure

症状: Pod が Pending state のままで、node がプロビジョニングされません

解決策:

  • Karpenter log を確認します
  • IAM permission を確認します
  • provisioner configuration を確認します
bash
# Check Karpenter logs
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter -c controller

# Check provisioner status
kubectl describe provisioner <name>

# Check pod events
kubectl describe pod <name>

2. Node Removal Issues

症状: 期待どおりに node が削除されません

解決策:

  • TTL 設定を確認します
  • node consolidation 設定を確認します
  • Pod draining status を確認します
bash
# Check node status
kubectl describe node <name>

# Check node labels
kubectl get node <name> --show-labels

# Check Karpenter logs
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter -c controller | grep "node termination"

3. Instance Type Selection Issues

症状: 予期しない instance type がプロビジョニングされます

解決策:

  • provisioner requirements を確認します
  • Pod resource request を確認します
  • availability zone constraint を確認します
bash
# Check provisioner requirements
kubectl get provisioner <name> -o yaml

# Check pod resource requests
kubectl describe pod <name>

# Check node information
kubectl describe node <name>

デバッグツール

bash
# Check Karpenter version
kubectl get deployment -n karpenter karpenter -o jsonpath="{.spec.template.spec.containers[0].image}"

# Check Karpenter logs
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter -c controller

# Check provisioner list
kubectl get provisioners

# Check node template list
kubectl get awsnodetemplates

# Check events
kubectl get events --sort-by='.lastTimestamp'

# Enable debug logs
kubectl patch configmap -n karpenter karpenter-global-settings --type merge -p '{"data":{"logLevel":"debug"}}'

まとめ

Karpenter は、Kubernetes cluster の node provisioning を自動化する強力な autoscaler です。workload 要件に基づいて適切な compute resource を動的にプロビジョニングし、アプリケーションの可用性を確保しながら cluster 効率を最適化します。

このドキュメントでは、Karpenter の基本概念、インストール方法、provisioner と node template の設定、interruption handling、さまざまな統合、Amazon EKS との統合、best practice、troubleshooting について説明しました。

Karpenter を使用することで、cluster 管理を簡素化し、resource utilization を最適化し、コストを削減できます。特に Amazon EKS のような cloud-managed Kubernetes 環境では、Karpenter の利点を最大限に活用できます。

次のステップ

  • Karpenter を使用したコスト最適化 strategy を実装する
  • さまざまな workload type 向けに provisioner を設定する
  • hybrid cluster architecture を設計する
  • Karpenter を他の Kubernetes tool と統合する
  • 高度な node lifecycle management strategy を開発する

参考資料

クイズ

この章で学んだ内容を確認するために、トピッククイズ に挑戦してください。