목차
- Karpenter란 무엇인가: Kubernetes 오토스케일링을 더 세밀하게
- 왜 도입했는가: 노드 프로비저닝 병목이 보이기 시작했습니다
- 실전 구현: EKS에 Karpenter 붙이면서 제가 잡았던 기준
- 1. 컨트롤러 설치 전 확인할 것
- 2. 설치 예시
- 3. NodeClass / NodePool 예시
- 4. 테스트용 워크로드로 검증
- 운영하면서 체감한 장점: 비용 절감과 성능 최적화 포인트
- ⚠️ 주의사항과 트러블슈팅: 여기서 많이 막혔습니다
- 1. 서브넷/보안 그룹 태그 누락
- 2. 인스턴스 요구 조건을 너무 빡빡하게 잡음
- 3. DaemonSet(데몬셋) 자원 계산을 과소평가
- 4. Consolidation(통합 축소) 설정이 너무 공격적일 때
- 검증과 결과 확인: 무엇을 보면 잘 되고 있다고 판단할까
- 정리 표: 어떤 환경에 특히 잘 맞았나
- 자주 묻는 질문: 도입 전에 많이 받았던 질문
- Q1. Cluster Autoscaler 대신 무조건 Karpenter가 답인가요?
- Q2. 스팟만 써도 되나요?
- Q3. 어떤 팀이 먼저 도입해보면 좋을까요?
- 마무리: 1년 써보니 결국 설계가 반이었습니다
[Kubernetes] Karpenter 오토스케일러 1년 사용 후기
Karpenter 오토스케일러 후기를 한 줄로 먼저 말씀드리면, EKS 운영에서 노드 증설 속도와 비용 통제가 동시에 좋아졌습니다. 저도 처음엔 "Cluster Autoscaler(클러스터 오토스케일러)로도 되는데 굳이?" 싶었거든요. 그런데 서비스가 늘고, 배치 작업이 섞이고, 팀별로 워크로드 특성이 달라지니까 기존 방식이 점점 답답해지더라고요. 특히 Kubernetes 오토스케일링을 노드 그룹 중심으로만 운영하면 빈 자원이 남아도는 순간이 꽤 자주 생깁니다. 실무에서 결국 비용은 숫자로 돌아오니까요.
제가 지난 1년 동안 홈랩과 업무 환경에서 비슷한 패턴으로 실험하고 운영해보니, Karpenter는 "노드를 미리 크게 잡아두는 습관"을 줄여주는 쪽에 강점이 있었습니다. 다만 마법은 아닙니다. 설정을 대충 하면 오히려 인스턴스 종류가 너무 넓게 열리거나, 반대로 너무 좁아서 스케일이 안 붙는 일도 생깁니다. 오늘 글에서는 제가 실제로 겪었던 삽질까지 포함해서, 왜 도입했고 어떻게 운영했고 무엇을 조심해야 하는지 정리해보겠습니다.
Amazon EKS 환경에서 Karpenter가 대기 중인 Pod를 보고 적절한 EC2 노드를 프로비저닝하는 전체 흐름을 보여주는 아키텍처 이미지입니다.
Karpenter란 무엇인가: Kubernetes 오토스케일링을 더 세밀하게
쉽게 말해 Karpenter는 Pod(파드)의 요구사항을 보고 바로 노드를 만들어주는 노드 프로비저너(node provisioner, 노드 생성기)입니다. 기존 Cluster Autoscaler는 미리 만들어둔 Auto Scaling Group(오토 스케일링 그룹)이나 Managed Node Group(관리형 노드 그룹)을 기준으로 증설을 판단합니다. 반면 Karpenter는 "지금 이 파드가 CPU, 메모리, 아키텍처, 스팟 여부를 이렇게 요구하네? 그럼 여기에 맞는 노드를 하나 올리자"에 더 가깝습니다.
처음엔 이게 뭔가 싶었는데, 실제로 써보니까 포인트가 명확하더라고요. 노드 그룹을 여러 개 미리 쪼개서 관리하던 부담이 줄어듭니다. 그리고 워크로드에 맞는 인스턴스 타입을 더 유연하게 고를 수 있어서 AWS EKS 비용 절감 관점에서 꽤 체감이 됐습니다.
| 항목 | Cluster Autoscaler | Karpenter |
|---|---|---|
| 기준 | 노드 그룹 중심 | 파드 요구사항 중심 |
| 유연성 | 사전 정의된 그룹 범위 내 | 인스턴스 선택 폭이 넓음 |
| 비용 최적화 | 그룹 설계에 크게 의존 | 빈 자원 축소에 유리 |
| 운영 포인트 | 노드 그룹 관리 | 요구사항과 제약 조건 설계 |
왜 도입했는가: 노드 프로비저닝 병목이 보이기 시작했습니다
제가 Karpenter를 본격적으로 보기 시작한 이유는 세 가지였습니다.
- 배치와 실시간 서비스가 같은 클러스터에 섞이면서 노드 성격이 달라졌습니다.
- Managed Node Group을 늘릴수록 운영 포인트가 많아졌습니다.
- 스팟(Spot)과 온디맨드(On-Demand)를 상황에 따라 유연하게 섞고 싶었습니다.
예전에는 팀별로 노드 그룹을 하나씩 나누면 깔끔해 보였거든요. 근데 시간이 지나면 태그, 라벨, 테인트(Taint, 특정 워크로드 제한), AMI, 서브넷, 보안 그룹까지 관리 포인트가 계속 늘어납니다. 결국 "지금 이 파드가 왜 여기 못 올라가지?"를 찾는 시간이 길어지더라고요. Karpenter는 그 문제를 완전히 없애주진 않지만, 적어도 노드 프로비저닝을 워크로드 관점으로 다시 정리하게 만들어줍니다.
실전 구현: EKS에 Karpenter 붙이면서 제가 잡았던 기준
여기서 중요한 포인트! Karpenter를 처음 붙일 때는 욕심내서 모든 워크로드를 한 번에 옮기지 않는 게 좋습니다. 저도 처음엔 한 번에 바꾸려다가 삽질 좀 했습니다 ㅎㅎ 작은 NodePool부터 시작해서 점진적으로 옮기는 게 훨씬 안전했습니다.
- 기본 EKS 클러스터와 워커 노드를 준비합니다.
- Karpenter용 IAM 권한과 인터럽션 처리 큐를 구성합니다.
- Karpenter 컨트롤러를 설치합니다.
- NodeClass와 NodePool을 최소 범위로 선언합니다.
- 특정 워크로드만 먼저 태워서 동작을 검증합니다.
1. 컨트롤러 설치 전 확인할 것
- 클러스터의 OIDC provider가 연결되어 있는지
- 서브넷과 보안 그룹에 Karpenter가 찾을 수 있는 태그가 있는지
- 기존 CNI, CoreDNS, metrics-server 같은 필수 애드온이 정상인지
특히 태그는 정말 중요합니다. 이거 하나 빠지면 로그만 보고 한참 헤맵니다.
2. 설치 예시
export CLUSTER_NAME=my-eks
export AWS_REGION=ap-northeast-2
export KARPENTER_NAMESPACE=karpenter
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm upgrade --install karpenter eks/karpenter \
--namespace ${KARPENTER_NAMESPACE} \
--create-namespace \
--set settings.clusterName=${CLUSTER_NAME} \
--set settings.interruptionQueue=${CLUSTER_NAME} \
--set serviceAccount.create=true
환경마다 IAM Role for Service Account(IRSA, 서비스어카운트용 IAM 역할) 구성 방식은 다를 수 있습니다. 그래서 설치 커맨드 자체보다도, 컨트롤러가 EC2 인스턴스 생성과 조회 권한을 제대로 갖고 있는지를 먼저 보는 게 중요합니다.
3. NodeClass / NodePool 예시
아래 예시는 운영에서 자주 쓰는 방향을 단순화한 것입니다. 핵심은 "너무 넓지도, 너무 좁지도 않게" 시작하는 겁니다.
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: my-eks
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: my-eks
role: KarpenterNodeRole-my-eks
---
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: general
spec:
template:
metadata:
labels:
workload: general
spec:
nodeClassRef:
name: default
requirements:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
- key: node.kubernetes.io/instance-type
operator: In
values: ["m5.large", "m5.xlarge", "m6i.large", "m6i.xlarge"]
disruption:
consolidationPolicy: WhenUnderutilized
limits:
cpu: "100"
제가 직접 해보니 처음부터 인스턴스 타입을 수십 개 열어두는 것보다, 검증된 계열 몇 개로 시작하는 편이 좋았습니다. 나중에 확장하는 건 쉽지만, 처음부터 범위를 넓히면 왜 그 타입이 선택됐는지 추적이 어려워지거든요.
EC2NodeClass와 NodePool이 연결되어 서브넷, 보안 그룹, 인스턴스 타입, capacity type을 결정하는 구조를 보여주는 구성 이미지입니다.
4. 테스트용 워크로드로 검증
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 6
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
nodeSelector:
workload: general
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
cpu: "500m"
memory: "512Mi"
이렇게 요청 리소스(requests, 예약 자원)를 명시한 테스트 파드를 올려보면 스케줄링이 안 되는 순간 Karpenter가 새 노드를 붙이는 흐름을 직관적으로 볼 수 있습니다. 드디어 됐다! 하는 순간이 여기서 나옵니다.
운영하면서 체감한 장점: 비용 절감과 성능 최적화 포인트
Karpenter 오토스케일러 후기에서 가장 많이 물어보는 게 "그래서 돈이 진짜 줄었나요?"인데요, 제 경우엔 AWS EKS 비용 절감 효과를 숫자 하나로 단정하긴 어려웠습니다. 워크로드 패턴이 계속 바뀌니까요. 다만 분명했던 변화는 있었습니다.
- 대기 중인 파드 처리 속도가 좋아졌습니다. 노드 그룹 단위보다 반응이 직관적이었습니다.
- 빈 자원이 남는 노드가 줄었습니다. 특히 야간 배치 종료 후 차이가 컸습니다.
- 스팟과 온디맨드 혼합 전략을 잡기 쉬웠습니다.
- 팀별 노드 그룹 난립을 줄이면서 운영 복잡도가 낮아졌습니다.
성능 최적화라는 게 꼭 CPU 사용률 그래프만 예쁘게 만드는 건 아니더라고요. 스케줄링 지연이 줄고, 워크로드 특성에 맞는 노드가 더 빨리 생기고, 과하게 큰 노드를 덜 쓰게 되는 것 자체가 운영 품질 향상입니다. 실제로 써보니까 이 부분이 더 크게 다가왔습니다.
⚠️ 주의사항과 트러블슈팅: 여기서 많이 막혔습니다
이 섹션은 좀 중요합니다. Karpenter는 잘 되면 정말 편한데, 안 될 때는 로그와 이벤트를 꼼꼼히 봐야 하거든요.
1. 서브넷/보안 그룹 태그 누락
가장 흔했습니다. 컨트롤러는 떠 있는데 노드가 안 생깁니다. 원인은 대개 discovery 태그 누락이었습니다.
kubectl logs -n karpenter deploy/karpenter
kubectl describe nodepool general
kubectl get events -A --sort-by=.lastTimestamp
해결: 서브넷과 보안 그룹 선택 조건에 맞는 태그가 있는지 다시 확인했습니다. 이건 문서보다 실제 AWS 리소스 태그 화면이 더 빠르더라고요.
2. 인스턴스 요구 조건을 너무 빡빡하게 잡음
저도 처음엔 특정 세대, 특정 사이즈만 고집했습니다. 그러면 순간적으로 가용한 인스턴스가 없을 때 스케일이 멈춥니다. 특히 스팟만 강제하면 더 민감해집니다.
- 인스턴스 패밀리를 1개만 두지 말 것
- 사이즈를 한 단계 이상 열어둘 것
- 스팟만 고정하지 말고 온디맨드 fallback을 고려할 것
3. DaemonSet(데몬셋) 자원 계산을 과소평가
이거 진짜 많이 놓칩니다. 노드 하나가 올라오면 CNI, 로그 에이전트, 모니터링 에이전트 같은 DaemonSet이 먼저 자리를 먹거든요. 파드 request를 딱 맞춰 잡아두면 생각보다 노드가 더 필요해집니다.
해결: 시스템 DaemonSet이 차지하는 CPU/메모리를 감안해서 워크로드 request를 다시 계산했습니다. 제가 직접 해보니 이 조정만으로도 불필요한 추가 스케일링이 꽤 줄었습니다.
4. Consolidation(통합 축소) 설정이 너무 공격적일 때
유휴 노드를 잘 정리해주는 기능은 좋지만, 워크로드 패턴이 들쭉날쭉하면 노드가 자주 교체될 수 있습니다. 배치가 짧게 반복되는 환경에서는 오히려 흔들릴 수 있겠더라고요.
해결: 처음엔 보수적으로 운영하고, 패턴이 보인 뒤에 consolidation 정책을 조정했습니다. 이건 정답이 하나가 아니라 워크로드 성격을 타는 부분입니다.
검증과 결과 확인: 무엇을 보면 잘 되고 있다고 판단할까
Karpenter 오토스케일러 후기를 쓰면서 가장 조심한 부분이 여기입니다. 비용 수치나 처리량 수치를 함부로 적으면 안 되거든요. 그래서 저는 운영에서 다음 지표를 기준으로 판단했습니다.
- Pending Pod가 줄어드는 속도
- 피크 시간 이후 유휴 노드가 정리되는지
- 스팟 중단 이후 재스케줄링이 안정적인지
- 특정 노드 그룹에 과도하게 몰리던 패턴이 줄었는지
kubectl get nodes
kubectl get pods -A -o wide
kubectl top nodes
kubectl top pods -A
kubectl describe pod <pending-pod-name>
제가 실제로 써보니까, 가장 눈에 띄는 건 노드 수 자체보다도 대기 중인 파드가 오래 머무르지 않는 것이었습니다. 클러스터가 바빠질 때 운영자가 덜 초조해집니다. 이건 체감이 꽤 큽니다.
파드 증가 시 노드가 빠르게 늘고, 부하가 줄면 유휴 노드가 정리되는 모습을 대시보드 형태로 보여주는 결과 이미지입니다.
정리 표: 어떤 환경에 특히 잘 맞았나
| 환경 | Karpenter 적합도 | 이유 |
|---|---|---|
| 배치와 웹 서비스 혼합 | 높음 | 워크로드별 노드 요구사항 차이가 큼 |
| 스팟 적극 활용 | 높음 | capacity type 전략을 유연하게 설계 가능 |
| 소규모 고정 트래픽 | 보통 | 정적 노드 그룹만으로도 충분할 수 있음 |
| 규제가 강한 고정 인스턴스 정책 | 보통 이하 | 유연성 장점이 줄어듦 |
자주 묻는 질문: 도입 전에 많이 받았던 질문
Q1. Cluster Autoscaler 대신 무조건 Karpenter가 답인가요?
그건 아닙니다. 워크로드가 단순하고 노드 그룹이 적다면 기존 방식도 충분히 안정적입니다. 다만 노드 그룹이 많아지고 Kubernetes 오토스케일링 설계가 복잡해질수록 Karpenter의 장점이 커졌습니다.
Q2. 스팟만 써도 되나요?
중단 허용성이 높은 워크로드라면 가능하지만, 핵심 서비스는 온디맨드 fallback을 함께 두는 게 마음이 편합니다. 저도 처음엔 공격적으로 갔다가 다시 섞어서 운영했습니다.
Q3. 어떤 팀이 먼저 도입해보면 좋을까요?
배치 작업, CI 러너, 일시적인 이벤트성 워크로드가 있는 팀부터 추천드립니다. 효과가 빨리 보입니다.
Cluster Autoscaler와 Karpenter의 차이점, 추천 사용 시나리오, 운영 포인트를 한 장에 요약한 비교 인포그래픽 이미지입니다.
마무리: 1년 써보니 결국 설계가 반이었습니다
Karpenter는 분명 좋은 도구입니다. 하지만 설치했다고 끝나는 종류는 아니었습니다. 어떤 인스턴스를 허용할지, 어떤 워크로드를 어디에 태울지, 스팟과 온디맨드를 어떻게 섞을지, consolidation을 얼마나 공격적으로 둘지 같은 정책 설계가 훨씬 중요했습니다. 저도 처음엔 도구가 다 알아서 해줄 줄 알았는데, 실제로 써보니까 "잘 설계된 제약 조건"이 핵심이더라고요.
그래도 1년 기준으로 돌아보면, Karpenter 오토스케일러 후기는 꽤 긍정적입니다. 노드 프로비저닝이 더 민첩해졌고, 불필요한 여유 자원을 줄이는 방향으로 운영 습관이 바뀌었습니다. 혹시 지금 EKS에서 노드 그룹이 점점 복잡해지고 있다면, 작은 워크로드 하나부터 붙여보셔도 좋겠습니다. 다음 글에서는 HPA(Horizontal Pod Autoscaler, 파드 수평 확장)와 Karpenter를 같이 운영할 때 생기는 타이밍 이슈도 다뤄볼 예정입니다. 이전 글의 EKS 운영 체크리스트와 함께 보시면 흐름이 더 잘 잡히실 겁니다.
1년 운영 후 배운 점, 추천 도입 순서, 주의할 설정 포인트를 요약한 마무리 이미지입니다.
'IT > k8s' 카테고리의 다른 글
| [k8s] EKS 운영 비용 최적화 전략: 클라우드 지출 효율 높이기 (1) | 2026.07.21 |
|---|---|
| [k8s] Prometheus Operator vs 직접 설정: Kubernetes 모니터링 실전 비교 분석 (1) | 2026.07.18 |
| [Kubernetes] Kubernetes PodSecurity 도입 전후 비교: 보안 강화 사례 연구 (0) | 2026.07.17 |
| [Kubernetes] StatefulSet vs Deployment: 상태 저장 애플리케이션 배포 비교 (0) | 2026.07.17 |
| [k8s] Backstage 운영 후기: 개발자 포털 1년 회고와 정착 과정 (0) | 2026.07.14 |
| [k8s] Pod Security Standards 마이그레이션: Kubernetes PSP에서 안전하게 전환하기 (0) | 2026.07.14 |