쿠버네티스 (Kubernetes) 주요 용어 Karpenter
1. Karpenter란?
Karpenter는 쿠버네티스(Kubernetes) 클러스터의 노드 자동 확장을 위한 오픈소스 프로젝트로, AWS에서 개발하여 2021년에 공개되었습니다. Karpenter의 주요 목적은 워크로드 수요에 맞게 적절한 컴퓨팅 리소스를 신속하게 프로비저닝하고 제거하는 것입니다.
Karpenter라는 이름은 “Kubernetes”와 “Carpenter(목수)”의 합성어로, 클러스터 내 자원을 효율적으로 ‘구축’한다는 의미를 담고 있습니다.
2. Karpenter의 필요성
기존 자동 확장의 문제점
기존 쿠버네티스 환경에서는 Cluster Autoscaler(CA)가 노드 자동 확장을 담당해왔습니다. 그러나 CA는 다음과 같은 여러 제약이 있었습니다:
- 노드 그룹 기반 작동: 미리 정의된 노드 그룹에 의존하기 때문에 유연성이 제한됨
- 확장 속도 제한: 노드 추가 시간이 길어 급격한 트래픽 증가에 대응하기 어려움
- 리소스 낭비: 사전 정의된 인스턴스 유형만 사용할 수 있어 최적의 리소스 활용이 어려움
- 복잡한 설정: 다양한 워크로드에 맞춰 여러 노드 그룹을 구성해야 함
Karpenter의 해결책
Karpenter는 이런 문제들을 해결하기 위해 설계되었습니다:
- 빠른 확장: 수십 초 내에 새 노드 프로비저닝
- 워크로드 중심 접근: 노드 그룹이 아닌 워크로드 요구사항에 따라 최적의 인스턴스 선택
- 자동 최적화: 리소스 활용도를 지속적으로 모니터링하고 최적화
- 단순화된 관리: 복잡한 노드 그룹 구성 없이도 효율적인 확장 가능
3. 기존 솔루션과의 차이점
| 기능 | Cluster Autoscaler | Karpenter |
|---|---|---|
| 확장 방식 | 노드 그룹 기반 | 워크로드 요구사항 기반 |
| 확장 속도 | 수 분 | 수십 초 |
| 인스턴스 유형 선택 | 노드 그룹별 고정 | 워크로드에 최적화하여 동적 선택 |
| 리소스 활용도 | 제한적 최적화 | 지속적인 최적화 |
| 관리 복잡성 | 높음 (여러 노드 그룹 관리) | 낮음 (간단한 프로바이더 설정) |
| 클라우드 통합 | 간접적 | 직접적 (클라우드 API 직접 호출) |
4. Karpenter 작동 방식
Karpenter는 다음과 같은 핵심 구성요소로 작동합니다:
1. 프로비저너(Provisioner)
프로비저너는 Karpenter의 핵심 리소스로, 노드 프로비저닝에 대한 전반적인 정책을 정의합니다.
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: default
spec:
requirements:
- key: "karpenter.k8s.aws/instance-category"
operator: In
values: ["c", "m", "r"]
limits:
resources:
cpu: 1000
providerRef:
name: default
ttlSecondsAfterEmpty: 30
2. 노드 템플릿(Node Template)
AWS 환경에서는 AWSNodeTemplate을 사용하여 노드의 세부 설정을 구성합니다.
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
name: default
spec:
subnetSelector:
karpenter.sh/discovery: my-cluster
securityGroupSelector:
karpenter.sh/discovery: my-cluster
tags:
environment: production
3. 워크플로우
- 모니터링: Karpenter는 스케줄링되지 않은 Pod를 지속적으로 모니터링
- 결정: Pod 요구사항에 맞는 최적의 노드 유형 결정
- 프로비저닝: 클라우드 제공자 API를 호출하여 노드 생성
- 통합: 노드를 쿠버네티스 클러스터에 등록
- 관리: 리소스 활용도를 지속적으로 모니터링하고 필요에 따라 노드 제거
5. 사용 예시
기본 설치 (AWS EKS)
AWS EKS 환경에서 Karpenter를 설치하고 구성하는 기본 예시입니다.
- 필요한 IAM 역할 및 정책 설정:
eksctl create iamserviceaccount \
--cluster=my-cluster \
--namespace=karpenter \
--name=karpenter \
--attach-policy-arn=arn:aws:iam::aws:policy/AmazonEKSClusterPolicy \
--approve
- Helm을 통한 Karpenter 설치:
helm repo add karpenter https://charts.karpenter.sh
helm repo update
helm install karpenter karpenter/karpenter \
--namespace karpenter \
--create-namespace \
--set serviceAccount.annotations."eks\\.amazonaws\\.com/role-arn"=${KARPENTER_IAM_ROLE_ARN} \
--set clusterName=${CLUSTER_NAME} \
--set clusterEndpoint=${CLUSTER_ENDPOINT}
- 프로비저너 및 노드 템플릿 생성:
# provisioner.yaml
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: default
spec:
requirements:
- key: "karpenter.k8s.aws/instance-category"
operator: In
values: ["c", "m", "r"]
- key: "karpenter.k8s.aws/instance-generation"
operator: Gt
values: ["4"]
limits:
resources:
cpu: 100
memory: 400Gi
providerRef:
name: default
ttlSecondsUntilExpired: 604800 # 7일
---
# node-template.yaml
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
name: default
spec:
subnetSelector:
karpenter.sh/discovery: my-cluster
securityGroupSelector:
karpenter.sh/discovery: my-cluster
blockDeviceMappings:
- deviceName: /dev/xvda
ebs:
volumeSize: 100Gi
volumeType: gp3
deleteOnTermination: true
tags:
environment: production
실제 워크로드 예시
다양한 워크로드 요구사항에 맞는 Karpenter 구성 예시입니다.
1. 머신러닝 워크로드를 위한 GPU 노드 자동 프로비저닝
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: gpu-provisioner
spec:
requirements:
- key: "node.kubernetes.io/instance-type"
operator: In
values: ["p3.2xlarge", "p3.8xlarge", "p3.16xlarge"]
- key: "accelerator"
operator: Exists
labels:
workload-type: gpu
taints:
- key: nvidia.com/gpu
value: "true"
effect: NoSchedule
providerRef:
name: gpu-template
2. 비용 최적화를 위한 스팟 인스턴스 활용
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
name: spot-template
spec:
subnetSelector:
karpenter.sh/discovery: my-cluster
securityGroupSelector:
karpenter.sh/discovery: my-cluster
instanceProfile: KarpenterNodeInstanceProfile
capacityType: spot
3. 시간 기반 노드 관리 예시
특정 시간에만 노드를 유지하도록 구성:
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: batch-jobs
spec:
requirements:
- key: "karpenter.k8s.aws/instance-category"
operator: In
values: ["c", "m"]
ttlSecondsAfterEmpty: 60 # 1분 후 노드 제거
ttlSecondsUntilExpired: 14400 # 4시간 후 강제 교체
6. 결론
Karpenter는 쿠버네티스 클러스터의 자동 확장에 혁신적인 접근 방식을 제공합니다. 기존의 Cluster Autoscaler와 달리, Karpenter는 워크로드 요구사항을 기반으로 최적의 노드를 신속하게 프로비저닝하고 관리함으로써 다음과 같은 이점을 제공합니다:
- 비용 최적화: 필요한 리소스만 정확히 프로비저닝
- 빠른 확장: 수십 초 내에 워크로드 요구사항 충족
- 운영 간소화: 복잡한 노드 그룹 구성 없이 자동화된 관리
- 리소스 효율성: 워크로드에 맞춰 최적의 인스턴스 유형 자동 선택
특히 변동성이 큰 워크로드, 다양한 인스턴스 요구사항, 대규모 클러스터를 운영하는 환경에서 Karpenter의 가치가 극대화됩니다. 쿠버네티스 생태계의 발전과 함께 Karpenter는 클라우드 리소스 관리의 새로운 표준으로 자리잡아가고 있습니다.
참고 자료
7. Consolidation (통합) 기능
Consolidation은 Karpenter의 핵심 비용 최적화 기능으로, 유휴 노드를 자동으로 제거하거나 여러 노드의 파드를 더 적은 수의 노드에 통합합니다.
Consolidation 동작 방식
| 모드 | 설명 |
|---|---|
| WhenEmpty | 파드가 없는 빈 노드만 제거 |
| WhenUnderutilized | 파드를 다른 노드로 이동시켜 노드 수 감소 |
# NodePool에서 Consolidation 설정
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
disruption:
consolidationPolicy: WhenUnderutilized # 비용 최적화
consolidateAfter: 30s # 30초 후 통합 시도
budgets:
- nodes: "20%" # 한 번에 최대 20% 노드만 교체
template:
spec:
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"]
Disruption Budget (중단 예산)
# 중요 워크로드 보호: PodDisruptionBudget과 함께 사용
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2 # 최소 2개 파드 유지
selector:
matchLabels:
app: web-server
주의:
do-not-disrupt어노테이션을 파드에 추가하면 Karpenter가 해당 파드의 노드를 교체하지 않습니다.annotations: karpenter.sh/do-not-disrupt: "true"
8. 비용 모니터링
Karpenter + AWS Cost Explorer 연동
# 노드 비용 태그 자동 적용 (EC2NodeClass)
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
tags:
Environment: production
Team: platform
CostCenter: engineering
ManagedBy: karpenter
Prometheus + Grafana로 Karpenter 메트릭 모니터링
# Karpenter는 기본적으로 Prometheus 메트릭 제공 (포트 8080)
# 주요 메트릭
| 메트릭 | 설명 |
|---|---|
karpenter_nodes_total |
프로비저닝된 노드 수 |
karpenter_pods_state |
파드 스케줄링 상태 |
karpenter_provisioner_scheduling_duration_seconds |
스케줄링 소요 시간 |
karpenter_interruption_received_messages_total |
Spot 인터럽션 수신 횟수 |
karpenter_nodes_termination_duration_seconds |
노드 종료 소요 시간 |
# Prometheus ServiceMonitor 설정
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: karpenter
namespace: karpenter
spec:
selector:
matchLabels:
app.kubernetes.io/name: karpenter
endpoints:
- port: http-metrics
interval: 30s
path: /metrics
Spot 인터럽션 처리
Karpenter는 EC2 Spot 인터럽션 알림을 자동으로 처리합니다.
# Spot 인터럽션 발생 시 Karpenter 동작:
# 1. AWS SQS로 인터럽션 알림 수신
# 2. 영향받는 노드의 파드를 다른 노드로 이동 (Cordon + Drain)
# 3. 새 노드 프로비저닝 (On-Demand 또는 다른 Spot 타입)
# SQS 큐 생성 (Spot 인터럽션 알림용)
aws cloudformation deploy \
--template-file interruption-queue.yaml \
--stack-name karpenter-interruption-queue
댓글남기기