- Published on
EKS Karpenter 노드 드리프트로 비용 폭증 잡기
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
EKS에서 Karpenter를 도입하면 노드 프로비저닝이 민첩해지고 스팟·온디맨드 혼합 최적화도 쉬워집니다. 그런데 운영 중 어느 날부터 노드가 계속 교체되고(드리프트), 파드가 자주 재스케줄링되며, 스팟이 아닌 비싼 인스턴스가 늘어나 비용이 폭증하는 케이스가 종종 발생합니다.
이 글은 “드리프트가 왜 생기고”, “어떤 메커니즘으로 비용을 밀어 올리며”, “어떻게 진단하고 제어할지”를 Karpenter 관점에서 실전적으로 정리합니다.
노드 드리프트란 무엇이고 왜 비용이 오르나
Karpenter에서 드리프트는 간단히 말해 현재 떠 있는 노드가, Karpenter가 원하는 스펙/정책과 ‘불일치’ 상태가 되는 것입니다. 이 불일치를 감지하면 Karpenter는 노드를 교체(드레인 후 새 노드 생성)하여 원하는 상태로 되돌리려 합니다.
문제는 이 교체가 다음의 비용 패턴을 만들 수 있다는 점입니다.
과도한 노드 교체로 순간 용량이 2배
- 드레인 중에는 기존 노드가 유지되고, 동시에 새 노드가 떠서 파드가 이동합니다.
- 이 과정이 자주 반복되면 “항상 일부 노드가 교체 중” 상태가 되어 평균 비용이 상승합니다.
스케줄링 실패로 더 큰 인스턴스 선택
- 파드의
requests/limits,nodeSelector,affinity,topologySpreadConstraints가 빡빡하면 Karpenter는 더 큰 인스턴스(또는 온디맨드)로 수렴합니다. - 드리프트로 교체가 반복되면 이 수렴이 더 자주 발생합니다.
- 파드의
스팟 중단 + 드리프트 교체가 겹쳐 “불필요한 온디맨드” 증가
- 스팟 중단이 잦은 워크로드에서, 드리프트까지 겹치면 안정성을 위해 온디맨드 비중이 올라가거나, 결과적으로 더 비싼 대체 인스턴스를 선택할 확률이 커집니다.
DaemonSet/이미지 풀/초기화 지연으로 교체 비용 증가
- 노드가 자주 바뀌면 이미지 풀, CNI 초기화, 로그/모니터링 에이전트(DaemonSet) 기동 비용이 누적됩니다.
- 이미지 풀 실패가 동반되면 교체가 더 길어지고 중복 용량이 오래 유지됩니다. 이때는 EKS ImagePullBackOff - ECR 인증·IRSA·노드캐시 진단도 함께 점검하는 게 좋습니다.
드리프트를 유발하는 대표 원인
드리프트 원인은 “노드가 바뀌는 게 정상”인 것과 “불필요하게 바뀌는 것”이 섞여 있습니다. 비용 폭증은 보통 후자에서 발생합니다.
1) AMI/런타임/부트스트랩 변경
- EKS 최적화 AMI 버전 변경, Bottlerocket 업그레이드, 컨테이너 런타임 설정 변경 등
- NodeClass(또는 NodeTemplate)에서 AMI 셀렉터가 바뀌면 기존 노드가 불일치로 판단될 수 있습니다.
2) NodeClass(보안그룹/서브넷/태그) 변경
- 서브넷 셀렉터 태그 수정, 보안그룹 교체, IMDS 설정 변경 등
- 특히 서브넷 태그를 손대면 “새 노드는 다른 AZ/서브넷으로만 생성 가능”해져 드리프트가 연쇄적으로 발생할 수 있습니다.
3) NodePool(구 Provisioner) 요구사항 변경
requirements에 인스턴스 패밀리/세대/아키텍처 제한을 추가하거나 변경capacity-type을spot위주로 바꾸거나, 반대로 온디맨드 강제
4) 만료(expire) 정책 또는 통합(Consolidation) 정책
expireAfter같은 만료 정책이 너무 짧으면 “정상 노드도 주기적으로 교체”됩니다.- Consolidation이 공격적으로 동작하면, 워크로드 변동이 큰 환경에서 계속 재배치가 일어날 수 있습니다.
5) 파드 스케줄링 제약이 사실상 “노드 교체를 강제”
PodDisruptionBudget이 너무 엄격하거나- 특정 노드 라벨에 강하게 묶여 있거나
topologySpreadConstraints가 AZ 단위로 강제되는데, 해당 AZ에 스팟이 부족한 경우
이 경우 드리프트가 트리거된 뒤 드레인이 길어지고, 새 노드는 더 비싼 선택지로 올라가며, 결과적으로 비용이 상승합니다.
비용 폭증 시 30분 내 1차 진단 체크리스트
1) Karpenter 이벤트/로그에서 드리프트 사유 확인
먼저 “정말 드리프트가 원인인지”를 확인해야 합니다.
kubectl -n karpenter logs deploy/karpenter -f | grep -i drift
또는 노드/노드클레임(버전에 따라 리소스 명이 다를 수 있음) 이벤트를 봅니다.
kubectl get events -A --sort-by=.lastTimestamp | tail -n 50
핵심은 로그에 나오는 “불일치 항목”입니다. 예를 들어 AMI, 서브넷, 보안그룹, 요구사항 변경 등이 드러납니다.
2) “노드가 교체 중이라 평균 용량이 늘었는지” 확인
kubectl get nodes
kubectl get pods -A -o wide | grep -E 'Pending|ContainerCreating|Terminating'
Terminating파드가 길게 남아있으면 드레인 지연Pending이 늘면 더 큰 인스턴스/온디맨드로 튈 가능성 증가
Pending이 길어지면 파드 자체 이슈(예: CrashLoopBackOff로 재시작 폭증)도 비용 증가로 이어질 수 있어, 필요하면 Kubernetes CrashLoopBackOff 원인 7가지·즉시복구도 같이 점검하세요.
3) 스팟 비중이 갑자기 줄었는지 확인
CloudWatch나 Cost Explorer에서 Spot 사용량이 급감하고 On-Demand가 증가했다면,
- 스팟 부족(특정 AZ/패밀리)
- 요구사항 변경으로 스팟 후보군 축소
- 드리프트 교체 중 안정성 우선 선택 을 의심할 수 있습니다.
드리프트를 “통제 가능한 변화”로 만드는 전략
전략 A: 드리프트가 발생해도 “한 번에 조금씩”만 교체되게 만들기
핵심은 드리프트 자체를 0으로 만들기보다, 교체 속도를 제어해 비용 스파이크를 막는 것입니다.
- 워크로드별
PodDisruptionBudget재점검
- 너무 엄격하면 드레인이 길어져 중복 노드 유지 시간이 늘어납니다.
- 반대로 너무 느슨하면 서비스 영향이 커집니다.
예시:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
namespace: app
spec:
minAvailable: 80%
selector:
matchLabels:
app: api
- 안전한 종료를 위한
terminationGracePeriodSeconds와 프리스트롭 드레인 지연을 줄이려면 애플리케이션이 SIGTERM에 빠르게 반응해야 합니다.
spec:
terminationGracePeriodSeconds: 30
containers:
- name: api
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"]
전략 B: Karpenter NodePool 설계를 “비용 상한”이 생기게 분리
하나의 NodePool에 모든 워크로드를 몰아 넣으면, 드리프트나 스팟 부족 시 전체가 비싼 인스턴스로 튈 수 있습니다.
critical(온디맨드 고정, 인스턴스 범위 제한)default(스팟 우선, 후보군 넓게)batch(스팟 전용, 중단 허용)
처럼 분리하면 드리프트가 발생해도 비용이 폭발하는 범위를 줄일 수 있습니다.
아래는 개념 예시입니다(필드명은 설치 버전에 따라 다를 수 있으니 실제 CRD 스키마를 확인하세요).
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default-spot
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
- key: node.kubernetes.io/instance-type
operator: In
values: ["m6a.large", "m6a.xlarge", "c6a.large", "c6a.xlarge"]
disruption:
consolidateAfter: 10m
포인트:
- 스팟 후보군을 너무 좁히지 말 것
consolidateAfter같은 값을 너무 공격적으로 두면 변동성 큰 환경에서 재배치가 잦아질 수 있음
전략 C: AMI/NodeClass 변경은 “점진 롤아웃”으로
드리프트의 가장 흔한 트리거가 AMI/NodeClass 변경입니다. 운영에서는 아래 순서가 안전합니다.
- 새 NodeClass 생성(기존 수정 대신)
- 새 NodePool을 만들어 일부 네임스페이스/워크로드만 타게팅
- 안정화 후 기존 NodePool을 단계적으로 축소
이렇게 하면 드리프트가 “전체 노드 동시 교체”로 번지는 걸 막습니다.
전략 D: 스팟 중단과 드리프트가 겹치지 않게 “시간대/정책” 조정
- 배치/비동기 워크로드는 야간에 대량 실행되는데, 같은 시간대에 드리프트 교체까지 겹치면 용량이 흔들립니다.
- 가능하면 AMI 롤아웃, 노드 정책 변경을 트래픽 한산한 시간으로 고정하고, 배치 윈도우와 분리하세요.
실전: 드리프트 원인별 해결 레시피
레시피 1) 서브넷/보안그룹 태그 변경으로 드리프트 폭발
증상:
- 특정 AZ로만 노드가 생기거나
- 새 노드가 아예 안 떠서
Pending이 급증 - 동시에 기존 노드가 드리프트로 종료 대상
대응:
- 최근 변경된 VPC 태그/서브넷 태그/보안그룹 셀렉터를 되돌리거나
- NodeClass 셀렉터를 더 넓게(다중 서브넷) 잡아 후보군을 복구
- AZ 편향이 생겼다면
topologySpreadConstraints완화 검토
레시피 2) 인스턴스 타입 요구사항을 너무 좁혀 온디맨드로 튐
증상:
- 스팟 후보가 부족해지며 온디맨드가 급증
대응:
instance-type을 특정 1~2개로 고정하지 말고 패밀리/세대 단위로 넓히기- CPU 아키텍처(arm64/amd64) 혼용 가능하면 후보군 확대
레시피 3) 드레인 지연으로 중복 노드 유지 시간이 길어짐
증상:
- 노드는 떠 있는데 파드가 오래
Terminating - PDB 때문에 eviction이 막히거나
- 애플리케이션이 종료 신호를 무시
대응:
- PDB 재조정
terminationGracePeriodSeconds를 합리적으로 줄이고 SIGTERM 처리- 종료 훅이 외부 의존성 때문에 오래 걸리면 타임아웃 도입
관측(Observability): “드리프트 비용”을 숫자로 보이게 하기
비용 폭증을 막으려면 “드리프트가 얼마나 자주, 얼마나 오래” 발생하는지 지표화해야 합니다.
추천 지표/대시보드:
- 노드 생성/종료 빈도(시간당)
- 노드 평균 수명
Pending파드 수(시간대별)- 스팟 대비 온디맨드 비율
- 드레인에 걸린 평균 시간(노드 종료 요청부터 실제 종료까지)
Karpenter 컨트롤러 로그를 수집하고, drift/disruption 키워드 기반으로 카운트해도 1차 지표로 충분히 유용합니다.
운영 팁: 비용 폭증을 “재발”시키는 흔한 실수
- NodePool/NodeClass를 “수정”으로만 운영
- 기존 객체를 직접 수정하면 드리프트가 즉시 전면 적용될 수 있습니다.
- 새 객체를 만들고 점진 전환하는 방식이 안전합니다.
- 스팟 후보군을 지나치게 제한
- 특정 패밀리·특정 사이즈 고정은 스팟 시장 변동에 취약합니다.
- 애플리케이션 종료/시작 품질을 무시
- 노드 교체가 잦아질수록 앱의 기동/종료 품질이 비용과 가용성에 직결됩니다.
- 이미지 풀·권한 문제로 노드 교체가 길어짐
- 새 노드에서 ECR 인증/IRSA 문제로 이미지 풀 실패가 나면, 교체가 지연되고 중복 용량이 오래 유지됩니다. 관련해서는 EKS Pod에서 AWS SDK 자격증명 못찾음 해결 가이드도 함께 확인하면 좋습니다.
마무리: 드리프트는 “없애는 것”보다 “관리하는 것”
Karpenter의 노드 드리프트는 완전히 나쁜 현상이 아니라, 클러스터를 원하는 상태로 맞추는 자동화의 결과입니다. 다만 운영 환경에서는 작은 설정 변경 하나가 대규모 교체로 이어져 중복 용량 증가, 스팟 이탈, 스케줄링 왜곡을 만들며 비용 폭증으로 연결될 수 있습니다.
정리하면,
- 드리프트 사유를 로그/이벤트로 먼저 고정하고
- 교체 속도를 PDB와 종료 품질로 제어하며
- NodePool을 워크로드 성격별로 분리해 비용 상한을 만들고
- AMI/NodeClass 변경은 새 객체로 점진 롤아웃
이 네 가지를 지키면 “드리프트가 있어도 예산이 흔들리지 않는” EKS 운영이 가능합니다.