요약 : 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 할당되어 서비스 시작
'DevOps' 카테고리의 다른 글
| 노드에 파드 할당하기 (0) | 2026.05.13 |
|---|---|
| EKS에서 파드에 AWS 권한 부여하는 3가지 방법 (0) | 2026.05.10 |
| MSK Connect + Debezium 이용하여 CDC 파이프라인 구축 (0) | 2026.05.07 |
| OTel 과 CloudWatch 구분하기 (MSK 모니터링) (0) | 2026.05.06 |
| Otel(OpenTelemetry) (0) | 2026.05.05 |