Karpenter Overview: Kubernetes Node Autoscaling

Contents

A practical overview of Karpenter, a node provisioning tool that addresses the limitations of Cluster Autoscaler on Amazon EKS

Overview

Karpenter is an open-source Kubernetes node provisioner developed by AWS to overcome the limitations of the existing Cluster Autoscaler. First released in 2021, it is now establishing itself as a new standard for node lifecycle management in Kubernetes clusters.

Why Was Karpenter Needed?

Limitations of Cluster Autoscaler

The existing Cluster Autoscaler had the following problems.

1. Restricted Scaling Based on Node Groups

yaml
# 기존 방식: 미리 정의된 노드 그룹만 사용 가능
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-autoscaler-status
data:
  node-group-1: "t3.medium (2-20 nodes)"
  node-group-2: "t3.large (1-10 nodes)"
  # 새로운 워크로드 요구사항이 생기면? 노드 그룹 추가 필요! 😰

2. Slow Scaling

bash
# 전통적인 스케일링 과정
Pod 스케줄 실패 → ASG 스케일 아웃 → 인스턴스 시작 → kubelet 등록
# 평균 3-5분 소요 😴

3. Inefficient Resource Utilization

yaml
# 실제 필요: CPU 1.5 코어, 메모리 3GB
# 할당된 노드: t3.large (2 코어, 8GB) - 50% 이상 낭비! 💸

Karpenter's Approach

Diagram 1Pod 생성 요청부터 Karpenter 감지, 인스턴스 타입 계산, EC2 직접 프로비저닝, Pod 스케줄링 완료까지의 순서와 기존 방식·Karpenter 소요 시간이다.Pod 생성 요청Karpenter가 실시간 감지최적 인스턴스 타입 계산직접 EC2 인스턴스 프로비저닝Pod 스케줄링 완료기존 방식: 3-5분Karpenter: 30초-1분
Pod 생성 요청부터 Karpenter 감지, 인스턴스 타입 계산, EC2 직접 프로비저닝, Pod 스케줄링 완료까지의 순서와 기존 방식·Karpenter 소요 시간이다.

Karpenter's Core Architecture

Main Components

1. Karpenter Controller

yaml
# Karpenter의 두뇌 역할
apiVersion: v1
kind: Pod
metadata:
  name: karpenter-controller
spec:
  containers:
  - name: controller
    image: public.ecr.aws/karpenter/karpenter:v0.37.0
    # 실시간 Pod 스케줄링 요구사항 모니터링
    # 최적 인스턴스 선택 알고리즘 실행
    # 노드 라이프사이클 관리

2. NodePool (Formerly Provisioner)

yaml
# Karpenter v0.32+ 에서 도입된 새로운 리소스
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: default
spec:
  # 노드 프로비저닝 템플릿
  template:
    metadata:
      labels:
        node-type: "general-purpose"
    spec:
      # 노드 클래스 참조
      nodeClassRef:
        apiVersion: karpenter.k8s.aws/v1beta1
        kind: EC2NodeClass
        name: default
      # 인스턴스 요구사항
      requirements:
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["t3.medium", "t3.large", "t3.xlarge"]
      # Taints 적용
      taints:
        - key: "workload-type"
          value: "batch"
          effect: NoSchedule
  # 스케일링 제한
  limits:
    cpu: 1000
  # 중단 정책
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s
    expireAfter: 2160h # 90일

3. EC2NodeClass

yaml
# AWS EC2 인스턴스 세부 설정
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
  name: default
spec:
  # AMI 선택
  amiFamily: AL2
  
  # 서브넷 자동 선택
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "my-cluster"
  
  # 보안 그룹 자동 선택  
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "my-cluster"
  
  # IAM 인스턴스 프로파일
  instanceProfile: "KarpenterNodeInstanceProfile"
  
  # 사용자 데이터 커스터마이징
  userData: |
    #!/bin/bash
    /etc/eks/bootstrap.sh my-cluster
    # 추가 커스터마이징...
  
  # 블록 디바이스 매핑
  blockDeviceMappings:
    - deviceName: /dev/xvda
      ebs:
        volumeSize: 100Gi
        volumeType: gp3
        encrypted: true

How It Works

1. Real-Time Scheduling Detection

yaml
# Pod가 pending 상태가 되면 즉시 감지
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        cpu: "500m"
        memory: "1Gi"
  # 이 Pod가 스케줄링 안 되면 Karpenter가 즉시 반응!

2. Optimal Instance Selection Algorithm

bash
# Karpenter의 스마트한 계산 과정
1. Pod 리소스 요구사항 분석
   - CPU: 500m
   - Memory: 1Gi
   
2. 가능한 인스턴스 타입 평가
   - t3.small (1 vCPU, 2GB): ✅ 적합
   - t3.medium (2 vCPU, 4GB): ✅ 적합 (여유 있음)
   - t3.large (2 vCPU, 8GB): ❌ 과도한 스펙
   
3. 비용 최적화 선택
   - t3.small 선택 ($0.0208/시간)
   
4. 즉시 프로비저닝 시작

3. Fast Provisioning Process

Diagram 2Pod Pending 감지부터 인스턴스 계산·생성 요청, 노드 등록, 스케줄링 완료까지 Pod·Karpenter·EC2·EKS 사이 순서와 단계별 시간이다.EKS ClusterAWS EC2KarpenterPodEKS ClusterAWS EC2KarpenterPod기존 ASG 방식 대비 3-4배 빠름!Pod Pending 감지최적 인스턴스 계산 (5초)인스턴스 생성 요청 (10초)노드 등록 (30초)Pod 스케줄링 완료 (45초)
Pod Pending 감지부터 인스턴스 계산·생성 요청, 노드 등록, 스케줄링 완료까지 Pod·Karpenter·EC2·EKS 사이 순서와 단계별 시간이다.

Key Features

1. Multi-Architecture Support

yaml
# ARM64와 AMD64 혼합 사용
apiVersion: karpenter.sh/v1beta1
kind: NodePool
spec:
  template:
    spec:
      requirements:
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64", "arm64"]
        - key: node.kubernetes.io/instance-type
          operator: In
          values: 
            - "t4g.medium"    # ARM64 Graviton
            - "t3.medium"     # x86_64

2. Spot Instance Optimization

yaml
# 스팟과 온디맨드 혼합으로 비용 절감
spec:
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
      # 스팟 인스턴스 우선 사용으로 80% 비용 절감!

3. Fine-Grained Resource Control

yaml
# GPU, 네트워크 성능 등 다양한 요구사항 지원
spec:
  template:
    spec:
      requirements:
        # GPU 인스턴스만 선택
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["p3.2xlarge", "p3.8xlarge"]
        # 향상된 네트워킹 필요
        - key: karpenter.k8s.aws/instance-network-bandwidth
          operator: Gt
          values: ["10000"]

Consolidation: Node Optimization

Concept and Purpose

Consolidation is a core Karpenter feature that reduces costs by optimizing node resource utilization.

The Problem

yaml
# 현재 클러스터 상태
Node-1 (t3.large): CPU 20%, Memory 30% 사용률
Node-2 (t3.large): CPU 15%, Memory 25% 사용률  
Node-3 (t3.large): CPU 10%, Memory 20% 사용률
# → 총 3개 노드가 모두 저사용률! 💸 비용 낭비

After Consolidation

yaml
# 최적화 후
Node-1 (t3.large): CPU 45%, Memory 75% 사용률 
# Node-2, Node-3 제거됨
# → 66% 비용 절감! 🎉

Consolidation Configuration

1. Basic Consolidation Configuration

yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
spec:
  disruption:
    # 언제 consolidation을 수행할지 정의
    consolidationPolicy: WhenEmpty | WhenUnderutilized
    
    # consolidation 실행 대기 시간
    consolidateAfter: 30s
    
    # 노드가 비어있을 때만 consolidation (안전한 옵션)
    # consolidationPolicy: WhenEmpty

2. Advanced Consolidation Configuration

yaml
spec:
  disruption:
    # 적극적 consolidation - 저사용률 노드도 정리
    consolidationPolicy: WhenUnderutilized
    
    # consolidation 대기 시간 (더 빠른 반응)
    consolidateAfter: 15s
    
    # Pod disruption budget 고려
    # PDB가 있는 Pod는 보호됨

How Consolidation Works

Diagram 3사용률이 낮으면 재배치 검토, PDB·Anti-affinity 확인, 드레인과 재스케줄링, 빈 노드 종료로 이어지고 정상이면 모니터링을 계속한다.저사용률 감지정상 사용률Karpenter가 노드 사용률 모니터링사용률 임계값 확인Pod 재배치 가능성 검토PDB 및 Anti-affinity 규칙 확인Pod 드레인 및 재스케줄링빈 노드 종료비용 절감 완료!모니터링 계속
사용률이 낮으면 재배치 검토, PDB·Anti-affinity 확인, 드레인과 재스케줄링, 빈 노드 종료로 이어지고 정상이면 모니터링을 계속한다.

Hands-on: Measuring Consolidation Effects

bash
# 1. 현재 노드 상태 확인
kubectl get nodes -o custom-columns="NAME:.metadata.name,CPU-REQ:.status.allocatable.cpu,MEM-REQ:.status.allocatable.memory"

# 2. Pod 리소스 사용률 확인  
kubectl top nodes

# 3. Karpenter consolidation 로그 확인
kubectl logs -n karpenter deployment/karpenter -f | grep consolidation

# 예시 로그 출력
# {"level":"INFO","time":"2024-01-15T10:30:00Z","message":"consolidating nodes","nodes":["ip-10-0-1-100"]}
# {"level":"INFO","time":"2024-01-15T10:30:30Z","message":"deleted node","node":"ip-10-0-1-100"}

expireAfter: Node Lifecycle Management

Concept

expireAfter limits a node's maximum lifetime. It serves the following purposes.

Configuration

yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
spec:
  disruption:
    # 노드 최대 수명: 2160시간 (90일)
    expireAfter: 2160h
    
    # 다른 예시들
    # expireAfter: 24h    # 1일 (개발환경 적합)
    # expireAfter: 168h   # 1주일 (테스트환경)
    # expireAfter: 720h   # 30일 (일반적인 운영환경)
    # expireAfter: never  # 무제한 (비권장)

Practical Recommendations

expireAfter Settings by Environment

yaml
# 개발 환경: 비용 최우선
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: dev-nodepool
spec:
  disruption:
    expireAfter: 24h  # 매일 교체 (비용 절감)
    consolidationPolicy: WhenEmpty
---
# 스테이징 환경: 안정성과 비용 균형
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: staging-nodepool
spec:
  disruption:
    expireAfter: 168h  # 주간 교체
    consolidationPolicy: WhenUnderutilized
---
# 프로덕션 환경: 안정성 우선
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: prod-nodepool
spec:
  disruption:
    expireAfter: 720h  # 월간 교체
    consolidationPolicy: WhenEmpty  # 보수적 접근

Combining expireAfter with Other Policies

yaml
# 모든 정책을 함께 사용한 최적화 예시
spec:
  disruption:
    # 최대 30일 수명
    expireAfter: 720h
    
    # 빈 노드는 30초 후 정리
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s
    
    # 추가 정책들
    replacePolicy: WhenHealthy  # 건강하지 않은 노드 교체

Practical Implementation Guide

1. Install Karpenter and Configure the Basics

Create an IAM Role for Service Accounts (IRSA)

bash
# 1. Karpenter를 위한 IAM 역할 생성
export CLUSTER_NAME="my-eks-cluster"
export AWS_REGION="ap-northeast-2"

# Karpenter Controller IAM Role 생성
eksctl create iamserviceaccount \
  --cluster=$CLUSTER_NAME \
  --namespace=karpenter \
  --name=karpenter \
  --role-name=${CLUSTER_NAME}-karpenter \
  --attach-policy-arn=arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \
  --approve

Install Karpenter with Helm

bash
# 2. Karpenter 설치
helm repo add karpenter https://charts.karpenter.sh/
helm repo update

helm upgrade --install karpenter karpenter/karpenter \
  --version v0.37.0 \
  --namespace karpenter \
  --create-namespace \
  --set settings.clusterName=$CLUSTER_NAME \
  --set settings.defaultInstanceProfile=KarpenterNodeInstanceProfile \
  --set settings.interruptionQueueName=$CLUSTER_NAME \
  --wait

2. A Phased NodePool Configuration Strategy

Phase 1: Basic NodePool (A Safe Start)

yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: general-purpose
spec:
  template:
    spec:
      nodeClassRef:
        name: default
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand"]  # 온디맨드만 사용 (안전)
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["t3.medium", "t3.large"]  # 검증된 인스턴스만
  limits:
    cpu: 100  # 작은 제한으로 시작
  disruption:
    consolidationPolicy: WhenEmpty  # 보수적 정책
    consolidateAfter: 60s
    expireAfter: 720h  # 30일

Phase 2: Introduce Spot Instances

yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: spot-optimized
spec:
  template:
    spec:
      nodeClassRef:
        name: default
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]  # 스팟 우선 사용
      # 스팟 인터럽션 대응을 위한 taints
      taints:
        - key: "node.kubernetes.io/spot"
          value: "true"
          effect: NoSchedule
  limits:
    cpu: 500
  disruption:
    consolidationPolicy: WhenUnderutilized  # 적극적 최적화
    consolidateAfter: 30s
    expireAfter: 168h  # 더 짧은 수명

Phase 3: Workload-Specific NodePools

yaml
# GPU 워크로드용
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: gpu-workload
spec:
  template:
    metadata:
      labels:
        node-type: "gpu"
    spec:
      nodeClassRef:
        name: gpu-nodeclass
      requirements:
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["p3.2xlarge", "p3.8xlarge"]
      taints:
        - key: "nvidia.com/gpu"
          value: "true"
          effect: NoSchedule
  limits:
    cpu: 1000
  disruption:
    consolidationPolicy: WhenEmpty  # GPU는 보수적으로
    expireAfter: 2160h  # 더 긴 수명 (비싼 인스턴스)

3. Monitoring and Cost Optimization

Check Karpenter Metrics

bash
# 1. Karpenter가 생성한 노드들 확인
kubectl get nodes -l karpenter.sh/provisioner-name

# 2. NodePool 상태 확인  
kubectl get nodepools

# 3. Karpenter 이벤트 확인
kubectl get events -n karpenter --sort-by='.lastTimestamp'

# 4. 비용 추적을 위한 태그 확인
aws ec2 describe-instances \
  --filters "Name=tag:karpenter.sh/cluster,Values=$CLUSTER_NAME" \
  --query 'Reservations[].Instances[].[InstanceId,InstanceType,State.Name]'

Cost Optimization Script

bash
#!/bin/bash
# cost-analysis.sh

echo "=== Karpenter 비용 분석 ==="

# 현재 실행 중인 노드들
RUNNING_NODES=$(kubectl get nodes -l karpenter.sh/provisioner-name --no-headers | wc -l)
echo "📊 Karpenter 관리 노드 수: $RUNNING_NODES"

# 인스턴스 타입별 분포
echo "📈 인스턴스 타입 분포:"
kubectl get nodes -l karpenter.sh/provisioner-name -o jsonpath='{.items[*].metadata.labels.node\.kubernetes\.io/instance-type}' | tr ' ' '\n' | sort | uniq -c

# 스팟 vs 온디맨드 비율
echo "💰 Capacity Type 분포:"
kubectl get nodes -l karpenter.sh/provisioner-name -o jsonpath='{.items[*].metadata.labels.karpenter\.sh/capacity-type}' | tr ' ' '\n' | sort | uniq -c

# 예상 시간당 비용 (간단 계산)
SPOT_COUNT=$(kubectl get nodes -l karpenter.sh/provisioner-name,karpenter.sh/capacity-type=spot --no-headers | wc -l)
ONDEMAND_COUNT=$(kubectl get nodes -l karpenter.sh/provisioner-name,karpenter.sh/capacity-type=on-demand --no-headers | wc -l)

echo "💸 예상 시간당 비용:"
echo "  - Spot 인스턴스: $SPOT_COUNT 개 (평균 $0.05/시간)"
echo "  - On-Demand: $ONDEMAND_COUNT 개 (평균 $0.20/시간)"
echo "  - 총 예상 비용: $$(echo "$SPOT_COUNT * 0.05 + $ONDEMAND_COUNT * 0.20" | bc)/시간"

Precautions and Best Practices

1. Gradual Adoption Strategy

A Phased Approach

yaml
# Stage 1: 개발환경에서 검증 (1-2주)
환경: Development
위험도: Low
설정: 보수적 (온디맨드, WhenEmpty)

# Stage 2: 스테이징에서 부하 테스트 (2-3주)  
환경: Staging
위험도: Medium
설정: 중간 (스팟 혼합, WhenUnderutilized)

# Stage 3: 프로덕션 부분 적용 (4-6주)
환경: Production (non-critical workload)
위험도: Medium-High
설정: 최적화된 설정

# Stage 4: 프로덕션 전면 적용
환경: Production (all workloads)
위험도: High
설정: 검증된 최종 설정

2. Spot Instance Response Strategy

Handle Spot Interruptions

yaml
# 스팟 친화적 워크로드 설정
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      # 스팟 노드를 허용하는 toleration
      tolerations:
      - key: "node.kubernetes.io/spot"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"
      
      # 스팟 선호도
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 50
            preference:
              matchExpressions:
              - key: karpenter.sh/capacity-type
                operator: In
                values: ["spot"]
      
      # 인터럽션 대응을 위한 설정
      terminationGracePeriodSeconds: 30

3. Cost Governance

Configure Budget Limits

yaml
# 노드풀별 리소스 제한
apiVersion: karpenter.sh/v1beta1
kind: NodePool
spec:
  # 팀별/프로젝트별 리소스 제한
  limits:
    cpu: 1000      # 최대 1000 코어
    memory: 1000Gi # 최대 1TB 메모리
    
  template:
    metadata:
      # 비용 추적을 위한 라벨
      labels:
        team: "backend"
        project: "ecommerce"
        environment: "production"
    spec:
      # 비용 최적화 인스턴스만 허용
      requirements:
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["t3.medium", "t3.large", "t3.xlarge"]
          # 비싼 인스턴스 제외 (예: r5.24xlarge)

Performance and Cost Impact Analysis

Before vs After Comparison

Existing Cluster Autoscaler

yaml
# 문제점들
평균 노드 프로비저닝 시간: 3-5분 ⏰
리소스 낭비율: 30-50% 💸
운영 복잡도: 높음 😰
인스턴스 타입 유연성: 제한적 📦

# 월간 비용 (예시)
EC2 인스턴스 비용: $2,400
낭비되는 리소스: $1,200 (50%)
총 비용: $3,600/월

After Adopting Karpenter

yaml
# 개선 효과
평균 노드 프로비저닝 시간: 30초-1분 ⚡
리소스 낭비율: 10-20% ✅
운영 복잡도: 낮음 😊
인스턴스 타입 유연성: 매우 높음 🎯

# 월간 비용 (예시)
EC2 인스턴스 비용: $1,800 (스팟 활용)
낭비되는 리소스: $200 (10%)
총 비용: $2,000/월
절약액: $1,600/월 (44% 절감!) 💰

How to Measure in Practice

bash
# 성능 측정 스크립트
#!/bin/bash
# performance-test.sh

echo "=== Karpenter 성능 테스트 ==="

# 1. 노드 프로비저닝 시간 측정
echo "노드 프로비저닝 시간 테스트 시작..."
START_TIME=$(date +%s)

# 대용량 Pod 생성으로 노드 프로비저닝 유도
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: load-test
spec:
  replicas: 10
  selector:
    matchLabels:
      app: load-test
  template:
    metadata:
      labels:
        app: load-test
    spec:
      containers:
      - name: stress
        image: nginx
        resources:
          requests:
            cpu: 1000m
            memory: 1Gi
EOF

# Pod가 Running이 될 때까지 대기
kubectl wait --for=condition=Ready pod -l app=load-test --timeout=300s

END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))

echo "✅ 프로비저닝 완료 시간: ${DURATION}초"

# 2. 리소스 효율성 측정
echo "📊 리소스 사용률 분석:"
kubectl top nodes

# 정리
kubectl delete deployment load-test

Advanced Use Cases

1. Multi-Tenant Environment Configuration

yaml
# 팀별 전용 NodePool 구성
---
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: team-frontend
spec:
  template:
    metadata:
      labels:
        team: frontend
    spec:
      nodeClassRef:
        name: default
      # 프론트엔드 최적화 인스턴스
      requirements:
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["t3.medium", "t3.large"]
      taints:
        - key: "team"
          value: "frontend"
          effect: NoSchedule
  limits:
    cpu: 200
---
apiVersion: karpenter.sh/v1beta1
kind: NodePool  
metadata:
  name: team-backend
spec:
  template:
    metadata:
      labels:
        team: backend
    spec:
      nodeClassRef:
        name: default
      # 백엔드 최적화 인스턴스 (메모리 중심)
      requirements:
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["r5.large", "r5.xlarge"]
      taints:
        - key: "team"  
          value: "backend"
          effect: NoSchedule
  limits:
    cpu: 500

2. CI/CD Pipeline Optimization

yaml
# 빌드 전용 NodePool
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: ci-builds
spec:
  template:
    metadata:
      labels:
        workload-type: ci-build
    spec:
      nodeClassRef:
        name: build-optimized
      # 빌드에 최적화된 CPU 중심 인스턴스
      requirements:
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["c5.large", "c5.xlarge", "c5.2xlarge"]
        # 스팟 인스턴스로 비용 절감
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot"]
      taints:
        - key: "workload-type"
          value: "ci-build"  
          effect: NoSchedule
  limits:
    cpu: 100
  disruption:
    # 빌드 완료 후 빠른 정리
    consolidationPolicy: WhenEmpty
    consolidateAfter: 10s
    # 짧은 수명으로 비용 최적화
    expireAfter: 2h

3. Batch Job Optimization

yaml
# 배치 처리 전용 NodePool
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: batch-processing
spec:
  template:
    metadata:
      labels:
        workload-type: batch
    spec:
      nodeClassRef:
        name: batch-optimized
      requirements:
        # 대용량 메모리 인스턴스
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["r5.2xlarge", "r5.4xlarge", "r5.8xlarge"]
        # 스팟으로 최대 비용 절감
        - key: karpenter.sh/capacity-type
          operator: In  
          values: ["spot"]
      taints:
        - key: "workload-type"
          value: "batch"
          effect: NoSchedule
  disruption:
    # 배치 작업 완료 후 즉시 정리
    consolidationPolicy: WhenEmpty
    consolidateAfter: 5s
    # 매우 짧은 수명
    expireAfter: 4h

Troubleshooting Guide

1. Common Problems

Nodes Are Not Provisioned

bash
# 1. Karpenter 로그 확인
kubectl logs -n karpenter deployment/karpenter -f

# 2. NodePool 상태 확인
kubectl describe nodepool

# 3. Pod 이벤트 확인
kubectl describe pod <pending-pod-name>

# 일반적인 원인들:
# - IAM 권한 부족
# - 서브넷/보안그룹 태그 누락  
# - 인스턴스 한도 초과
# - NodePool 리소스 제한 도달

Consolidation Does Not Work

bash
# 1. PodDisruptionBudget 확인
kubectl get pdb --all-namespaces

# 2. Pod anti-affinity 규칙 확인  
kubectl get pods -o yaml | grep -A 10 "podAntiAffinity"

# 3. Karpenter consolidation 로그 확인
kubectl logs -n karpenter deployment/karpenter -f | grep -i consolidat

2. Emergency Response Guide

An Unexpected Surge in Scale-Out

bash
# 1. 긴급 NodePool 제한 설정
kubectl patch nodepool default --type='merge' -p='{"spec":{"limits":{"cpu":"100"}}}'

# 2. 특정 NodePool 일시 중지
kubectl patch nodepool batch-processing --type='merge' -p='{"spec":{"template":{"spec":{"requirements":[{"key":"node.kubernetes.io/instance-type","operator":"In","values":["t3.nano"]}]}}}}'

# 3. 불필요한 Pod 스케일 다운
kubectl scale deployment expensive-app --replicas=0

Conclusion and Practical Recommendations

Karpenter changes how Kubernetes nodes are managed. By overcoming the limitations of the existing Cluster Autoscaler, it provisions nodes faster and more cost-efficiently.

Key Success Factors

1. Phased Adoption

2. An Appropriate Policy Mix

3. Continuous Monitoring

Final Recommendations

Good Candidates for Adoption

Cases Requiring Careful Consideration

Practical Checklist

Before adoption:

After adoption:

Used appropriately, Karpenter can deliver both cost savings and operational efficiency.


References

  1. Karpenter Official Documentation
  2. AWS Karpenter Workshop
  3. Karpenter Best Practices Guide
  4. Karpenter vs Cluster Autoscaler Comparison
  5. Kubernetes Cluster Autoscaler Documentation

Diagram

100%

Drag to pan; pinch or use the wheel to zoom. Keyboard: arrow keys pan, + − zoom, 0 fits, Esc closes. The same content is in “Read the diagram as text” below the figure.