IT/AWS

EKS Auto Mode 켜고 첫 달 청구서 받고 멘붕한 이야기

gfrog 2026. 6. 9. 03:13
SMALL

지난달에 우리 팀이 운영하던 EKS 클러스터 두 개를 Auto Mode로 갈아탔다. "노드 관리 안 해도 된다", "Karpenter 직접 안 만져도 된다", 이런 얘기 듣고 한 달만에 슬쩍 옮긴 건데, 첫 달 청구서 받고 멘탈이 살짝 나갔다. 결론부터 말하면 망한 건 아니다. 다만 예상하고 옮긴 그림이랑은 꽤 달랐다는 얘기다.

어떻게 옮겼나

원래 우리 클러스터는 Karpenter 0.37로 NodePool 4개 돌리고 있었다. 일반 워크로드, batch job용 spot, GPU 추론, 그리고 좀 큰 메모리 잡아먹는 streaming consumer용. 인스턴스 타입은 직접 골랐다. m6i.2xlarge, r6i.4xlarge, g5.xlarge 이런 식으로. 한 1년 운영하면서 어떤 패밀리가 어디에 잘 맞는지 데이터가 좀 쌓여있던 상태였다.

EKS Auto Mode가 GA 된 게 2024년 말이고, 우리는 그동안 좀 지켜봤다. 올해 5월에 release note 한번 정리하다가 "이제 옮길만 하겠다" 싶었다. 마이그레이션 자체는 의외로 깔끔했다. 클러스터에 computeConfig.enabled: true 켜고, 기존 Karpenter NodeClaim들이 빠지면서 Auto Mode 노드로 갈리는데 한 15분 정도. AWS Load Balancer Controller, EBS CSI driver, VPC CNI 같은 것들이 Auto Mode 쪽에서 관리하기 시작해서 우리가 깔아둔 건 떼야 했다. helm uninstall 좀 하고.

그래서 뭐가 문제였나

옮기고 일주일은 평화로웠다. 노드도 잘 뜨고, 파드 스케줄링도 문제없고, 오히려 노드 ami 패치 알림 안 와서 좋다고까지 생각했다. 그런데 5월 청구서 중간 집계가 떠서 봤더니, EC2 비용이 전월 대비 약 24% 올라있었다. 워크로드는 거의 그대로인데.

처음엔 트래픽이 늘었나 싶어서 그라파나 한참 봤다. P99 레이턴시도 그대로, 요청 수도 그대로, replica 수도 비슷. 근데 노드 fleet의 인스턴스 mix가 완전히 바뀌어 있었다. Auto Mode가 기본 NodePool로 쓰는 general-purpose 클래스는 m, c, r 패밀리에서 자유롭게 고르는데, 우리 워크로드한테 자꾸 c6i.4xlargem6i.4xlarge 같은 좀 비싼 타입을 띄우고 있었다.

Karpenter 시절엔 우리가 직접 instance-size: 2xlarge 정도로 제한해뒀던 거다. 작은 타입 여러 개로 채우는 게 비용 최적화가 더 잘 된다는 걸 시행착오로 알았기 때문에. 근데 Auto Mode 기본값으로 가면 "consolidation 잘 되는 쪽"을 골라준다는 명목으로 큰 타입을 더 자주 잡는 것 같았다. 사실 큰 타입 하나 띄우는 게 작은 거 여러 개보다 EC2 가격 면에선 살짝 비싸기도 하고, spot 가용성도 다르다.

# 우리가 만든 커스텀 NodePool (default 옆에 추가)
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: workload-bound
spec:
  template:
    spec:
      requirements:
        - key: karpenter.k8s.aws/instance-size
          operator: In
          values: ["large", "xlarge", "2xlarge"]
        - key: karpenter.k8s.aws/instance-family
          operator: In
          values: ["m6i", "m6a", "c6i", "r6i"]
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
  limits:
    cpu: 1000
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 30s

Auto Mode가 NodePool 커스터마이즈를 막는 건 아니다. 다만 디폴트로는 그냥 general-purposesystem 두 개만 있어서 손 안 대면 그게 그대로 동작한다. 우리 같이 "어떤 타입 써야 하는지 데이터가 있는" 팀은 NodePool을 직접 한두 개 더 만들어 두는 게 맞았다.

그리고 노드 디버깅 못 한다는 게 생각보다 컸다

비용 다음으로 멘붕했던 건, 어느 새벽에 한 노드에서 파드들이 자꾸 evicted 되는 이슈가 떴을 때다. 평소 같으면 kubectl get node 보고, 노드 그룹 instance ID 찾아서 SSM session으로 들어가서 dmesg, journalctl -u kubelet 이런 거 보면서 원인 찾았을 거다. 근데 Auto Mode 노드는 SSM도 안 되고, SSH도 안 된다. AWS가 관리하는 노드라서 우리한테 권한이 아예 없다.

# 이거 그냥 안 됨
aws ssm start-session --target i-0xxxxxxxxx
# An error occurred (TargetNotConnected)

결국 그날은 노드 레벨 metric (node-exporter DaemonSet)이랑 kubelet log를 pod log로 뽑는 정도로 견뎠다. 컨테이너 안에서 보이는 만큼만 디버깅 가능하다는 거. 평소엔 신경 안 쓰는 보안 ISO 인증 받을 때 EDR agent를 어떻게 노드에 깔지 고민하는 팀들이 왜 Auto Mode 피하는지 그제야 좀 이해됐다. 우리 팀은 EDR을 DaemonSet으로 돌려도 되는 형태라 다행이긴 했는데, 이건 조직마다 사정이 다르다.

두 달째 어떻게 정리했는가

지금은 NodePool 두 개 추가해서 instance-size, family 명시해뒀고, batch/GPU 워크로드는 그냥 self-managed node group을 따로 빼서 hybrid 모드로 돌린다. 인보이스 추이는 옮기기 전 수준으로 거의 돌아왔다. 노드 ami 패치, kubelet 업그레이드, 보안 패치 같은 거 신경 안 써도 되는 건 확실히 좋다. 우리가 매달 노드 그룹 rollover 하느라 쓰던 시간이 절반 이하로 줄었다.

근데 솔직히, Auto Mode가 "그냥 켜면 다 해준다"는 마케팅 톤은 좀 조심해야 한다고 생각한다. NodePool 안 건드리면 비용은 올라갈 가능성이 더 높고, 노드에 접근 못 한다는 트레이드오프는 첫 장애 만나기 전엔 체감 안 된다. 이미 Karpenter 잘 굴리고 있는 팀이라면, 굳이 옮길 이유가 그렇게 강하진 않다는 게 한 달 써본 결론이다. 반대로 처음 EKS 시작하는 팀, 노드 관리 전담 인력이 없는 팀한테는 좋은 선택지다.

다음 달엔 Auto Mode 클러스터에서 GPU 노드만 self-managed로 빼는 패턴 정리해서 한 번 더 글 써보려고 한다. 혹시 비슷한 마이그레이션 했다가 비용 튄 경험 있으신 분 있으면 어떤 NodePool 설정으로 잡았는지 댓글 좀 남겨주세요.

BIG