DevOps

Karpenter 이해하기

YoonJong 2026. 5. 7. 08:11
728x90
반응형

요약 : Karpenter는 k8s 환경에서 인프라 관리를 수동적인 노드 그룹 관리에서 워크로드 중심의 자동화로 전환하는 핵심 도구.

MSA 환경에서 배포 속도와 비용 절감을 동시에 달성하고자 할때 필수적인 선택지.

 

--

 

karpenter는 AWS로 구축된 오픈 소스의 고성능 k8s 클러스터 오토스케일러이다.

원래 기존에는 EC2 Auto Scaling 과 Kuberntes Cluster Autoscaler를 사용했는데, Karpenter에 비해 상대적으로 복잡했다.

 

구분 Cluster Autoscaler Karpenter
추가 방식 미리 정의된 ASG 규모 확장 pod 스펙에 맞춰 EC2 인스턴스 즉시 생성
의사 결정 노드 그룹 내에서 부족한 자원 보충 모든 EC2 인프라를 대상으로 최적 타입 선택
확장 속도 노드 그룹 업데이트로 인해 상대적으로 느림 ASG를 거치지 않아 상대적으로 빠름
비용 최적화 노드 그룹 내 고정된 사양으로 낭비 발생 가능 Consolidation 기능을 통해 빈 노드 제거 및 통합

* Consolidation : 자원 통합 (노드 사용률을 실시간으로 분석해서 사용률이 낮은 노드의 pod를 다른 곳으로 옮기고 해당 노드를 삭제하여 비용 최적화)

 

주된 구성 요소

1. NodePool : 생성될 노드의 <정책>을 정의하는 설정 파일

 ㄴ 허용할 EC2 인스턴스 타입, 가용 영역, 온디맨드/스팟(capacity-type)  등을 설정

 ㄴ 클러스터 전체 자원 한도(limit) 지정 가능

 ㄴ 예시

# === Karpenter NodePool (Spot) - 배치 전용 ===
# Jenkins agent, Argo Workflows 배치 잡 전용 노드풀
# 배치 실행 시에만 노드 생성, 완료 후 즉시 삭제 (비용 최소화)
resource "kubernetes_manifest" "karpenter_nodepool_batch_spot" {
  manifest = {
    apiVersion = "karpenter.sh/v1"
    kind       = "NodePool"
    metadata = {
      name = "batch-spot"
    }
    spec = {
      weight = 80
      template = {
        metadata = {
          labels = {
            "nodegroup"        = "batch"
            "capacity-type"    = "spot"
            "kubernetes.io/os" = "linux"
          }
        }
        spec = {
          requirements = [
            {
              key      = "kubernetes.io/arch"
              operator = "In"
              values   = ["arm64"] # Graviton
            },
            {
              key      = "karpenter.sh/capacity-type"
              operator = "In"
              values   = ["spot"]
            },
            {
              key      = "karpenter.k8s.aws/instance-category"
              operator = "In"
              values   = ["c", "m", "r"]
            },
            {
              key      = "karpenter.k8s.aws/instance-cpu"
              operator = "In"
              values   = ["4"]
            },
          ]
          nodeClassRef = {
            group = "karpenter.k8s.aws"
            kind  = "EC2NodeClass"
            name  = "default"
          }
          expireAfter = "720h"
        }
      }
      limits = {
        cpu = "16" # 배치 동시 최대 4개 (4코어 × 4)
      }
      disruption = {
        consolidationPolicy = "WhenEmpty"
        consolidateAfter    = "1m" # 배치 완료 후 1분 내 노드 삭제
      }
    }
  }
}

 

2. EC2NodeClass : AWS 인프라 레벨의 <세부 사양>을 정의

 ㄴ 사용할 AMI(Bottlerocket 등), 서브넷, 보안 그룹을 태그 기반으로 선택

 ㄴ EBS 볼륨 및 상세한 AWS 리소스 구성 담당

 ㄴ 예시

# === Karpenter NodeClass ===
# 노드의 AMI, 서브넷, 보안그룹 등 인프라 설정
resource "kubernetes_manifest" "karpenter_nodeclass" {
  manifest = {
    apiVersion = "karpenter.k8s.aws/v1"
    kind       = "EC2NodeClass"
    metadata = {
      name = "default"
    }
    spec = {
      subnetSelectorTerms = [
        {
          tags = {
            "kubernetes.io/role/internal-elb" = "1"
          }
        }
      ]
      securityGroupSelectorTerms = [
        {
          tags = {
            "karpenter.sh/discovery" = local.cluster_name
          }
        }
      ]
      amiFamily = "Bottlerocket"
      amiSelectorTerms = [
        {
          alias = "bottlerocket@1.60.0"
        }
      ]
      role = module.karpenter.node_iam_role_name
    }
  }
}

 

--

 

동작 프로세스

1. pod 보류(pending) : 클러스터 자원 부족으로 인해 새로운 pod가 스케줄링 되지 못함.

2. Karpenter 감지: API 서버를 감시하던 Karpenter가 스케줄링 불가능한 pod 포착

3. 최적 자원 계산 : pod의 리소스 요청 (CPU/Memory), 선호도(Affinity), 톨러레이션(Toleration)을 분석

4. EC2 프로비저닝 : 계산된 결과를 바탕으로 인스턴스 조합 중 가장 비용 효율적인 타입 선택하여 실행

5. 노드 Ready 및 바인딩 : 신규 노드가 클러스터에 조인되면 즉시 pod 할당되어 서비스 시작

728x90
반응형