목차
- 1. 왜 EKS 비용은 생각보다 빨리 커질까요?
- 2. EKS 비용을 볼 때 꼭 나눠야 하는 4가지 축
- 3. 실전 1단계: 먼저 현재 사용량을 수치로 확인합니다
- 4. 실전 2단계: Node Group과 Autoscaling 구조부터 손봅니다
- 추천 접근 방식
- 5. 실전 3단계: requests/limits를 줄이는 게 진짜 핵심입니다
- 6. 실전 4단계: 로그, 스토리지, 네트워크도 같이 줄여야 합니다
- 7. ⚠️ 제가 실제로 자주 본 문제와 트러블슈팅
- 1) 스팟 노드만 늘렸더니 서비스가 불안정해진 경우
- 2) request를 너무 낮췄더니 HPA가 과민반응하는 경우
- 3) Bin Packing이 안 돼서 노드가 안 줄어드는 경우
- 4) 로그를 줄였더니 장애 분석이 어려워진 경우
- 8. 검증 방법: 비용이 정말 줄었는지 어떻게 확인할까?
- 9. 정리: EKS 비용 최적화는 할인보다 구조가 먼저입니다
[클라우드] EKS 비용 최적화 전략: 클라우드 지출 효율 높이기
EKS 비용 최적화는 AWS를 오래 운영할수록 더 민감해지는 주제입니다. 처음엔 서비스만 잘 뜨면 된다고 생각했는데, 어느 순간 청구서를 보면 CPU는 놀고 있고 노드는 과하게 떠 있고, 로그 저장 비용까지 슬금슬금 올라가더라고요. 저도 홈랩과 실제 운영 환경을 오가면서 비슷한 패턴을 여러 번 봤습니다. 특히 AWS EKS 운영을 하다 보면 워크로드는 늘지 않았는데 비용만 올라가는 구간이 꼭 옵니다. 그 시점부터는 성능 튜닝보다 먼저 해야 할 일이 비용 구조를 보는 일입니다.
이번 글에서는 제가 직접 현장에서 자주 적용했던 방법들을 공유하려고 합니다. Kubernetes(쿠버네티스) 클러스터에서 어디서 돈이 새는지, 어떤 순서로 손봐야 하는지 정리해볼 거예요. 무작정 인스턴스를 내리는 이야기가 아니라, 서비스 안정성을 최대한 해치지 않으면서 Kubernetes 비용 절감과 클라우드 비용 관리를 같이 가져가는 방법에 가깝습니다.
EKS 비용 구조를 노드, 스토리지, 네트워크, 관측 영역으로 나눠 보여주는 개요 이미지입니다.
1. 왜 EKS 비용은 생각보다 빨리 커질까요?
쉽게 말해 EKS는 "컨테이너만 쓰는 서비스"가 아닙니다. 실제 청구는 여러 층에서 발생하거든요. 컨트롤 플레인(Control Plane, 클러스터 제어 영역), EC2 노드(Node, 워커 서버), EBS(Elastic Block Store, 블록 스토리지), 데이터 전송, 로드밸런서, 로그 수집까지 다 합쳐져서 나옵니다. 그래서 Pod(파드) 몇 개 줄였다고 체감이 바로 안 오는 경우도 많습니다.
- 노드 과할당: 요청 리소스(request)가 실제 사용량보다 과하게 잡혀서 빈 서버를 계속 유지합니다.
- 상시 고정 용량: 피크 시간 기준으로 노드를 잡아두고 하루 종일 유지합니다.
- 분산 실패: 비슷한 워크로드가 여러 노드에 흩어져서 스케일 인(scale-in)이 안 됩니다.
- 스토리지/로그 방치: 안 쓰는 볼륨, 긴 로그 보관 기간이 누적됩니다.
- 네트워크 비용 누락: NAT Gateway, AZ 간 트래픽, Load Balancer 비용이 생각보다 큽니다.
여기서 중요한 포인트! EKS 비용 최적화는 "할인 상품 먼저 사기"보다 현재 사용 패턴을 정상화하는 게 우선입니다. 저도 처음엔 Savings Plans(세이빙 플랜)부터 볼까 했었는데, 실제로는 잘못된 리소스 요청값부터 정리하는 게 훨씬 효과가 컸습니다.
2. EKS 비용을 볼 때 꼭 나눠야 하는 4가지 축
제가 비용 분석할 때는 항상 네 가지로 쪼갭니다. 이렇게 나누면 어디를 먼저 줄여야 할지가 보입니다.
| 영역 | 무엇을 보나 | 자주 나오는 문제 | 우선 대응 |
|---|---|---|---|
| Compute | EC2 노드, Fargate 사용량 | 낮은 사용률, 과한 노드 수 | 오토스케일링, Bin Packing |
| Storage | EBS, 스냅샷, 로그 저장 | 미사용 볼륨, 긴 보관 기간 | 수명주기 관리, 정리 자동화 |
| Network | Load Balancer, NAT, 트래픽 | 불필요한 외부 통신 경로 | 엔드포인트, 경로 단순화 |
| Observability | 로그, 메트릭, 트레이싱 | 수집 과다, 샘플링 없음 | 필드 축소, 보관 기간 재설계 |
이 표를 기준으로 보면, 같은 "클라우드 비용 관리"라도 접근 방식이 완전히 달라집니다. 노드 문제를 로그 보관 기간으로 해결할 수는 없으니까요.
3. 실전 1단계: 먼저 현재 사용량을 수치로 확인합니다
비용 최적화는 감으로 하면 거의 실패합니다. 저도 예전에 "이 노드가 제일 비싸 보이네" 하고 줄였다가 배치 작업이 밀린 적이 있었습니다. 삽질 좀 했습니다 ㅎㅎ 그래서 지금은 반드시 사용량과 요청값을 같이 봅니다.
- namespace(네임스페이스)별로 어떤 팀/서비스가 많이 쓰는지 확인합니다.
- CPU/메모리 실제 사용량과 requests/limits 차이를 봅니다.
- 노드별 유휴율과 스케일 인 가능 여부를 확인합니다.
- Spot(스팟) 전환 가능한 워크로드를 분류합니다.
kubectl top nodes
kubectl top pods -A --sort-by=cpu
kubectl top pods -A --sort-by=memory
kubectl get pods -A -o wide
kubectl describe node <node-name>
여기에 metrics-server(메트릭 서버)나 Prometheus(프로메테우스, 모니터링 시스템)가 붙어 있으면 더 좋습니다. 핵심은 "실사용량 대비 요청값이 얼마나 부풀어 있는가"입니다. 실제로 써보니까 메모리 request를 넉넉하게 잡아둔 서비스들이 클러스터 비용을 조용히 밀어올리는 경우가 정말 많더라고요.
4. 실전 2단계: Node Group과 Autoscaling 구조부터 손봅니다
AWS EKS 운영에서 비용이 가장 크게 흔들리는 영역은 대체로 노드입니다. 그래서 저는 여기부터 들어갑니다. 대표적으로 Managed Node Group(관리형 노드 그룹)과 Karpenter(카펜터, 워크로드 기반 노드 프로비저닝 도구), Cluster Autoscaler(클러스터 오토스케일러)를 조합해 구조를 정리합니다.
운영 팁을 하나 말씀드리면, 모든 워크로드를 한 종류 노드에 태우는 건 나중에 꼭 비용 문제로 돌아옵니다. On-Demand(온디맨드)와 Spot을 분리하고, 시스템 워크로드와 일반 애플리케이션 워크로드를 구분해두는 게 좋습니다.
시스템 워크로드는 안정적인 온디맨드 노드에, 일반 서비스는 스팟 노드에도 분산하는 구성 예시입니다.
추천 접근 방식
- 기반 시스템용 소규모 온디맨드 노드 그룹 유지
- 일반 웹/API 워크로드는 오토스케일링 대상 그룹으로 분리
- 중단 허용 가능한 배치/잡(Job)은 스팟 전용으로 이동
- Pod Disruption Budget(파드 중단 예산)과 anti-affinity를 같이 점검
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: sample-api
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: sample-api
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
HPA(Horizontal Pod Autoscaler, 수평 파드 오토스케일러)를 붙일 때도 request 값이 엉망이면 오토스케일 기준이 제대로 안 먹히더라고요. 그래서 request/right-sizing(라이트사이징, 적정 용량 조정)을 먼저 하고 HPA를 적용하는 순서가 훨씬 안정적입니다.
5. 실전 3단계: requests/limits를 줄이는 게 진짜 핵심입니다
많은 분들이 EKS 비용 최적화라고 하면 인스턴스 타입부터 바꾸는데, 제가 직접 해보니 제일 먼저 손대야 할 건 Deployment(디플로이먼트) 리소스 설정이었습니다. 특히 초기값을 넉넉하게 잡아놓고 그대로 운영하는 팀이 많거든요.
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-api
spec:
replicas: 3
template:
spec:
containers:
- name: app
image: example/sample-api:stable
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "1Gi"
여기서 중요한 건 숫자 자체보다 실측 기반으로 줄였는가입니다. CPU는 낮은데 메모리만 치솟는 애플리케이션도 있고, 반대도 있습니다. VPA(Vertical Pod Autoscaler, 수직 파드 오토스케일러)를 참고용으로 쓰거나, 일정 기간 메트릭을 보고 수동 조정해도 충분히 효과를 볼 수 있습니다.
제가 보통 보는 체크포인트는 이렇습니다.
- 평균 사용량이 requests의 절반 이하로 오래 유지되는가
- OOMKilled(메모리 부족 종료) 이력이 있는가
- 배치 시간대와 일반 시간대 사용 패턴이 다른가
- limits 때문에 CPU throttling(스로틀링, CPU 제한)이 심한가
이 단계만 잘해도 Kubernetes 비용 절감 효과가 꽤 크게 납니다. 왜냐하면 스케줄러가 더 촘촘하게 파드를 배치할 수 있어서, 결과적으로 노드 수가 줄어들 가능성이 커지거든요.
6. 실전 4단계: 로그, 스토리지, 네트워크도 같이 줄여야 합니다
노드만 줄이고 끝내면 반쪽짜리입니다. CloudWatch Logs(클라우드워치 로그), EBS, Load Balancer, NAT 비용도 무시 못 하거든요. 처음엔 이게 뭔가 싶었는데, 실제 청구를 뜯어보면 로그 저장 비용이 꽤 눈에 띄는 환경도 있습니다.
aws logs describe-log-groups
aws ec2 describe-volumes --filters Name=status,Values=available
aws elbv2 describe-load-balancers
- 로그: 디버그 로그 상시 수집 금지, 보관 기간을 서비스 성격에 맞게 분리
- 스토리지: 미사용 EBS와 오래된 스냅샷 주기 점검
- 네트워크: 내부 통신은 가능하면 Internal Load Balancer와 VPC Endpoint 활용
- 이미지: 컨테이너 이미지 크기를 줄여 배포 시간과 캐시 비효율 감소
로그 보관 기간 조정, 미사용 볼륨 점검, 네트워크 경로 단순화 흐름을 설명하는 이미지입니다.
특히 NAT Gateway 비용은 조용히 커집니다. 외부 API 호출이 많은 워크로드나 잘못된 라우팅 구조가 있으면 생각보다 빨리 누적되더라고요. 혹시 청구서에서 네트워크 비용이 이상하게 높다면, 애플리케이션보다 먼저 통신 경로를 의심해보셔도 좋습니다.
7. ⚠️ 제가 실제로 자주 본 문제와 트러블슈팅
비용 줄이다가 장애 내면 말짱 도루묵이죠. 그래서 아래 항목은 꼭 같이 보셔야 합니다.
1) 스팟 노드만 늘렸더니 서비스가 불안정해진 경우
해결은 단순합니다. 상태 저장성(Stateful) 워크로드나 핵심 시스템 컴포넌트는 온디맨드에 남기고, 스팟은 중단 허용 가능한 서비스 위주로 태워야 합니다.
2) request를 너무 낮췄더니 HPA가 과민반응하는 경우
CPU 기준 HPA는 request 영향을 받습니다. request를 급격히 낮추면 스케일 아웃이 너무 빨라질 수 있습니다. 그래서 한 번에 크게 줄이지 말고, 며칠 단위로 관찰하면서 조정하는 게 안전합니다.
3) Bin Packing이 안 돼서 노드가 안 줄어드는 경우
Topology Spread Constraints(토폴로지 분산 제약), anti-affinity, DaemonSet(데몬셋) 자원 점유 때문에 흔히 생깁니다. 저도 처음엔 오토스케일러가 이상한 줄 알았는데, 실제로는 배치 정책 때문에 노드가 비워지지 않더라고요.
4) 로그를 줄였더니 장애 분석이 어려워진 경우
모든 로그를 다 버리면 안 됩니다. 애플리케이션 로그는 줄이더라도 감사 로그, 에러 로그, 핵심 접근 로그는 남겨야 합니다. 비용과 가시성(observability, 관측 가능성) 사이에서 선을 잘 잡아야 합니다.
8. 검증 방법: 비용이 정말 줄었는지 어떻게 확인할까?
최적화는 적용보다 검증이 더 중요합니다. 저는 보통 2주에서 4주 단위로 비교합니다. 하루 이틀 데이터만 보면 배치, 이벤트 트래픽, 배포 타이밍 때문에 판단이 왜곡되거든요.
- 변경 전/후 노드 수와 평균 사용률을 비교합니다.
- namespace별 requests 합계를 기록합니다.
- CloudWatch 또는 Prometheus에서 CPU/메모리 추세를 봅니다.
- AWS Cost Explorer에서 서비스별 비용 추세를 확인합니다.
- 장애, 재시작, 응답 지연이 늘지 않았는지 같이 체크합니다.
변경 전후 비용 추이, 노드 수, CPU/메모리 사용률을 함께 보여주는 검증용 대시보드 이미지입니다.
검증할 때는 이렇게 보시면 됩니다.
- 비용은 줄었는데 재시작이 늘었다면 과최적화일 수 있습니다.
- 노드 수는 같아도 여유 자원이 늘었다면 다음 단계 최적화 여지가 생긴 겁니다.
- 로그 비용만 줄었다면 Compute 최적화는 아직 덜 된 상태일 수 있습니다.
드디어 됐다! 싶은 순간은 보통 "같은 트래픽인데 노드 수가 줄고, 장애 지표는 그대로일 때"입니다. 이게 가장 건강한 절감입니다.
9. 정리: EKS 비용 최적화는 할인보다 구조가 먼저입니다
오늘 내용을 한 줄로 정리하면 이겁니다. EKS 비용 최적화는 인스턴스 가격표를 보는 작업이 아니라, 워크로드 배치 구조와 리소스 설정을 바로잡는 작업입니다. 저도 처음엔 할인 모델만 찾았었는데, 실제로 써보니까 request 조정, 오토스케일링 구조 정리, 로그/스토리지 수명주기 관리가 훨씬 먼저더라고요.
- 먼저 실제 사용량을 측정합니다.
- 그다음 requests/limits를 다듬습니다.
- 오토스케일링과 스팟 전략을 분리 적용합니다.
- 스토리지, 로그, 네트워크 비용까지 같이 봅니다.
- 마지막으로 Cost Explorer와 모니터링으로 검증합니다.
사용량 측정부터 검증까지의 실행 순서를 요약한 체크리스트형 인포그래픽입니다.
혹시 지금 EKS 청구서를 보고 "분명 서비스는 안 늘었는데 왜 이러지?" 싶으셨다면, 오늘 소개한 순서대로 한 번만 점검해보세요. 차이가 확실할 겁니다. 다음 글에서는 Karpenter와 Cluster Autoscaler를 어떤 기준으로 나눠 쓰는지, 그리고 스팟 운영 시 장애 반경을 어떻게 줄이는지 이어서 다뤄볼 예정입니다. 이전 글의 VPC 설계 내용과도 연결해서 보시면 더 이해가 쉬우실 거예요. 🎉
'IT > k8s' 카테고리의 다른 글
| [Kubernetes] VPA vs HPA: 리소스 오토스케일링 최적화 전략 비교 (1) | 2026.07.22 |
|---|---|
| [k8s] Loki로 Kubernetes 로그 중앙화: 효율적인 모니터링 구축 가이드 (1) | 2026.07.22 |
| [k8s] Prometheus Operator vs 직접 설정: Kubernetes 모니터링 실전 비교 분석 (1) | 2026.07.18 |
| [Kubernetes] Kubernetes PodSecurity 도입 전후 비교: 보안 강화 사례 연구 (0) | 2026.07.17 |
| [Kubernetes] Karpenter 오토스케일러 1년 사용 후기: 비용 절감과 성능 최적화 회고 (0) | 2026.07.17 |
| [Kubernetes] StatefulSet vs Deployment: 상태 저장 애플리케이션 배포 비교 (0) | 2026.07.17 |