FinOps — K8s 비용 최적화
K8s는 공짜가 아니다 — 비용을 보이게 하고, 최적화하고, 문화로 정착시키기
1. K8s 비용 구조
클라우드 K8s
| 항목 | 설명 |
|---|---|
| 노드(VM) 비용 | ✅ 가장 큰 비중. EC2/VM 인스턴스 비용 |
| 관리 비용 | EKS/AKS/GKE Control Plane 비용 (EKS: $0.10/h) |
| 네트워크 | 리전 간 트래픽, NAT Gateway |
| 스토리지 | PV(EBS, Disk), 스냅샷 |
| LB | LoadBalancer Service마다 클라우드 LB 비용 |
온프레미스 K8s
| 항목 | 설명 |
|---|---|
| 하드웨어 | 서버, 네트워크, 스토리지 CAPEX |
| 전력/냉각 | 데이터센터 운영 비용 |
| 인력 | K8s 운영 인력 비용 |
2. 비용 가시성
2.1 Kubecost
K8s 네이티브 비용 모니터링 도구.
| 기능 | 설명 |
|---|---|
| 네임스페이스별 비용 | 팀/서비스별 비용 할당 |
| 워크로드별 비용 | Deployment, StatefulSet 단위 비용 |
| 최적화 추천 | 과할당 리소스 탐지, requests/limits 추천 |
| 알림 | 예산 초과 시 알림 |
# Helm으로 설치
helm install kubecost cost-analyzer \
--repo https://kubecost.github.io/cost-analyzer/ \
-n kubecost --create-namespace
2.2 OpenCost
CNCF 오픈소스 비용 모니터링. Kubecost의 오픈소스 버전.
3. 리소스 최적화
3.1 requests/limits 적정화
| 문제 | 영향 | 해결 |
|---|---|---|
| requests 과다 | 노드를 비효율적으로 사용 (비용 증가) | VPA 추천값 활용, 실제 사용량 모니터링 |
| requests 과소 | 리소스 경쟁, 성능 저하 | 적절한 최솟값 보장 |
| limits 미설정 | OOMKill 위험 | limits 필수 설정 |
# 실제 사용량 확인
kubectl top pods -n production
# requests 대비 실제 사용량 비율을 모니터링
3.2 미사용 리소스 정리
| 대상 | 확인 방법 |
|---|---|
| 유휴 Pod | CPU/메모리 사용량 0에 가까운 Pod |
| 미사용 PVC | 아무 Pod에도 마운트되지 않은 PVC |
| 미사용 Service | Endpoints가 비어있는 Service |
| 미사용 ConfigMap/Secret | 아무 Pod에서도 참조하지 않는 것 |
3.3 Spot/Preemptible 인스턴스
| On-Demand | Spot/Preemptible | |
|---|---|---|
| 비용 | 100% | 60~90% 할인 |
| 안정성 | ✅ 보장 | ⚠️ 언제든 회수 가능 |
| 적합 | 상태 앱, DB | 무상태 앱, 배치, CI/CD |
4. 스케줄링 최적화
4.1 Karpenter (AWS)
Cluster Autoscaler의 대안. 더 빠르고 유연한 노드 프로비저닝.
| Cluster Autoscaler | Karpenter | |
|---|---|---|
| 속도 | 느림 (ASG 기반) | ✅ 빠름 (직접 EC2 호출) |
| 노드 다양성 | ASG별 인스턴스 타입 고정 | ✅ 자동으로 최적 인스턴스 선택 |
| Spot 통합 | 기본적 | ✅ 자동 Spot 선택 |
| Bin Packing | ❌ | ✅ 노드를 빈틈없이 채움 |
| 통합(Consolidation) | ❌ | ✅ 노드 수 자동 줄임 |
4.2 비피크 스케일다운
# CronJob으로 비피크 시간에 스케일 조절
# 22:00 → replicas 줄이기
# 08:00 → replicas 복원
5. FinOps 문화
| 실천 | 설명 |
|---|---|
| Chargeback | 팀별 실제 비용 청구 |
| Showback | 팀별 비용을 보여주기만 (청구 안 함) |
| 비용 알림 | 예산 초과 시 Slack/Email 알림 |
| 주기적 리뷰 | 월별 비용 리뷰 미팅 |
| 태깅 | 리소스에 팀/서비스 레이블 필수 |
다음 글
→ #18 Serverless on K8s — Knative