Karpenter 얘기는 이제 새롭지 않다. AWS re:Invent 때마다 나오고, 트위터에서도 마이그레이션 후기가 쏟아진다. 얼마 전 Salesforce가 1,000개 넘는 EKS 클러스터를 Karpenter로 옮겼다는 소식도 있었고. 그런데 우리 팀은 좀 늦게 결정한 편이다. 작년에 Cluster Autoscaler(이하 CA)에서 Karpenter로 넘겼고, 반년 정도 운영해봤다. 결론부터 말하면 이득은 있었다. 다만 처음 예상했던 이유들과는 조금 달랐다.
왜 넘어갔나
원래 이유는 명확했다. 노드 스케일링이 느리다. CA는 ASG 기반이라 unschedulable 파드가 생기면 → CA가 감지 → ASG desired capacity 조정 → EC2 프로비저닝 → kubelet join. 이 사이클이 평균 3~4분 걸렸다. Karpenter는 EC2 API를 직접 부르니까 45~60초에 끝난다는 얘기였다.
트래픽 스파이크가 자주 있는 서비스에서는 이 차이가 크다. HPA가 파드를 늘렸는데 노드가 모자라서 Pending 상태로 몇 분 대기하면, 그 동안 P99 레이턴시가 튄다. 이걸 잡고 싶었다.
두 번째는 비용. 인스턴스 타입을 세밀하게 고르지 못했다. m5.2xlarge ASG 하나에 다양한 파드를 올리다 보니 bin-packing 효율이 안 좋았고, Spot 활용도 제한적이었다. Karpenter는 파드 요구사항에 맞춰서 EC2 타입을 그때그때 고르니까 이론상 이득이었다.
좋았던 것
노드 프로비저닝 시간은 확실히 줄었다. 실제로 재보니 우리 클러스터에서는 평균 55초 정도. CA 시절 로그를 다시 뒤져보면 200초를 넘긴 사례도 흔했으니 3~4배 빨라진 셈이다. 트래픽 급증 시 파드 Pending 시간이 눈에 띄게 줄었고, 이건 곧 SLO에 반영됐다.
비용도 예상보다 줄었다. 처음엔 20% 정도 기대했는데 실제로는 EC2 비용이 30% 초반 감소. bin-packing이 확실히 나았고, 스팟실팟 비율을 자연스럽게 70%까지 올릴 수 있었다. CA로도 스팟은 쓸 수 있었지만 ASG를 온디맨드/스팟으로 나눠서 관리하는 게 번거로웠는데, Karpenter는 NodePool에 requirements만 잘 걸어두면 알아서 골라준다.
놓쳤던 것
여기부터가 진짜 이야기다.
1. Disruption budget 기본값의 위험
Karpenter v1부터 disruption budget이 노드풀 단위로 설정 가능해졌는데, 기본값이 10%다. 즉 노드의 10%까지는 동시에 자발적으로 disrupt(consolidation, drift 등)될 수 있다. 문제는 이게 스케줄 개념 없이 하루 종일 적용된다는 거다.
우리 팀이 놓친 게 이 부분이었다. 평일 낮 피크 시간에 consolidation이 돌면서 노드 여러 대가 동시에 drain됐고, 파드가 재스케줄링되면서 짧게 5xx가 튄 적이 있다. PDB를 다시 점검하고, disruption budget에 크론 스케줄을 얹었다.
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 5m
budgets:
- nodes: "10%"
- schedule: "0 9 * * mon-fri"
duration: 8h
nodes: "0"
평일 오전 9시부터 8시간 동안은 disruption을 완전히 얼린다. 이건 후에 안 사실인데, Karpenter 공식 문서에서도 이 패턴을 권장한다. 처음 세팅할 때 잘 안 보이는 게 함정.
2. 태그 실수로 노드가 안 뜨는 이슈
karpenter.sh/discovery=<cluster-name> 태그가 subnet과 security group에 붙어있어야 한다는 건 다들 안다. 근데 EKS의 default security group이나 노드 SG에 이 태그가 빠져있는 경우가 은근 많다. Terraform 모듈로 만들었으면 신경 안 써도 되지만, 우리처럼 클러스터가 여러 세대에 걸쳐 생성됐으면 반드시 확인해야 한다.
실제로 한 클러스터에서 신규 노드가 프로비저닝은 되는데 파드가 안 뜨는 문제가 있었다. security group 하나에 태그가 빠져있었고, Karpenter가 그 SG를 못 골라서 결국 kubelet이 API 서버에 붙질 못했다. 로그를 한참 보고서야 알았다.
3. PDB가 너무 엄격하면 마이그레이션 자체가 막힌다
CA는 노드를 굳이 안 없앤다. desired capacity를 유지하는 방향이라 consolidation이 없다. 그런데 Karpenter는 기본적으로 계속 consolidation을 시도한다. PDB minAvailable: 100% 같은 게 걸린 워크로드가 있으면 노드가 영영 못 사라진다.
마이그레이션 초반에 이 PDB들 때문에 노드가 안 줄어들어서 "왜 비용이 안 줄지?" 하고 몇 주를 헤맸다. 결국 팀별로 PDB를 다시 검토해서 실제로 필요한 값(예: maxUnavailable: 1)으로 완화했다. 이건 Karpenter 문제라기보단 그동안 관성으로 지나쳤던 설정을 강제로 손보게 된 셈이다.
그래서 뭘 쓰나
지금은 대부분 Karpenter로 옮겼다. 하지만 CA를 완전히 버린 건 아니다. 인스턴스 타입 제약이 심하거나 (GPU 노드처럼) ASG 기반 다른 툴링과 강하게 엮인 클러스터는 아직 CA다. 억지로 옮길 이유가 없다.
내가 다시 마이그레이션한다면 이렇게 하겠다.
- 첫날: disruption budget에 업무시간 freeze 걸고 시작한다. 나중이 아니라 처음부터.
- 첫 주: PDB 감사. Karpenter를 켜기 전에 워크로드별로 재검토한다.
- 첫 달: 태그가 붙은 서브넷/SG를 리스트업하고, IaC로 강제한다. 수동 배포된 리소스 있는지 grep도 필수.
Salesforce 사례처럼 1,000개 클러스터 마이그레이션 같은 거창한 얘기가 아니어도, 몇십 개 규모에서도 이런 실수는 반복된다. 우리도 그랬다.
열린 질문
한 가지 아직 정리 안 된 게 있다. EKS Auto Mode. 작년 말에 나온 이후로 좀 지켜보고 있는데, Karpenter를 관리형으로 감싸주는 형태다. 자체 운영하는 팀 입장에서 편리하긴 한데, 설정 자유도가 줄어드는 트레이드오프가 있다. 우리는 아직 안 옮겼다. 조금 더 성숙해질 때까지 기다려볼 생각이다. 혹시 프로덕션에서 Auto Mode 쓰시는 분 계시면 후기 공유 부탁드립니다.
'IT > AWS' 카테고리의 다른 글
| ALB 뒤에서 502가 뚝뚝 떨어지던 날의 회고 (0) | 2026.08.10 |
|---|---|
| Karpenter WhenEmptyOrUnderutilized 켰다가 밤새운 이야기 (0) | 2026.08.04 |
| ALB deregistration_delay를 30초로 뒀더니 배포마다 5xx가 튀던 이야기 (0) | 2026.07.16 |
| IRSA vs Pod Identity, 우리 팀이 결국 Pod Identity로 간 이유 (0) | 2026.07.13 |
| RDS Proxy 붙였더니 P99가 오히려 늘어난 이야기 (0) | 2026.07.04 |