Kubernetes를 위한 FinOps: 규모 조정, 스팟 인스턴스 및 비용 절감
프로덕션에서 Kubernetes를 사용하는 조직의 68%가 20~40% 더 많은 비용을 지출합니다. 필요 이상입니다(CNCF 비용 조사 2026). Kubernetes가 비효율적이어서가 아니라, 관대하고 손쉬운 프로비저닝과 적절한 크기 조정에는 운영 규율이 필요합니다. 는 평균 CPU 사용량이 15~20%이고 메모리가 30~40%인 결과 및 클러스터: 리소스 지불 하지만 사용하지 마세요.
Kubernetes를 위한 FinOps 측정, 최적화, 관리의 실천 클러스터 지출. 이번 글에서는 사용법을 알아보겠습니다 큐브코스트 에 대한 다음과 같은 네임스페이스 비용의 가시성 VPA 크기 조정에 도움이 됩니다. 자동 요청, 방법 카펜터 노드 빈 패킹 최적화 스팟 인스턴스를 사용하고 비용을 유지하기 위해 조직 수준에서 구현할 정책 시간이 지남에 따라 통제됩니다.
무엇을 배울 것인가
- 네임스페이스/팀 비용 가시성을 위해 Kubecost 설치 및 구성
- 꺼짐 모드의 VPA: 중단 없이 자동 크기 조정 권장 사항
- Karpenter: 최적의 노드 빈 패킹을 위한 통합
- Karpenter 및 인터럽트 관리를 사용하여 AWS/GCP/Azure의 스팟 인스턴스
- 팀 예산 도구로서의 ResourceQuota
- 낭비 및 비용 이상 현상에 대해 Prometheus에 경고
- 팀을 위한 지불 거절 시스템을 구축하는 방법
- 벤치마크: 각 기술을 통해 얻을 수 있는 실질적인 비용 절감
Kubernetes가 과잉 프로비저닝되는 경향이 있는 이유
최적화하기 전에 문제의 원인을 이해해야 합니다.
- 보수적인 요청: 팀은 "안전"을 위해 요청을 높게 설정합니다(예: 0.1을 사용하는 앱의 경우 CPU 1개). 요청에 따라 필요한 노드 수가 결정됩니다.
- 제한 = 요청: 많은 CI/CD 템플릿은 요청과 동일한 제한을 설정하여 체계적인 과잉 프로비저닝을 생성합니다.
- 빈 네임스페이스: 연중무휴로 유지되는 'Hello World' 포드가 포함된 개발 네임스페이스
- 대형 매듭: 비효율적인 빈 패킹을 사용하는 대규모 클라우드 인스턴스(32개 vCPU 노드의 2개 vCPU 포드)
- 팀에 대한 가시성 없음: 팀이 비용을 확인하지 못하면 최적화할 인센티브가 없습니다.
Kubecost: 네임스페이스 비용의 가시성
큐브코스트 Kubernetes 생태계에서 가장 많이 사용되는 FinOps 도구입니다. Prometheus에서 측정항목을 수집하고 클라우드 인스턴스 가격(AWS, GCP, Azure)을 검색합니다. 네임스페이스, 배포, 서비스 계정 및 라벨에 할당된 비용을 계산합니다.
큐브코스트 설치
# Installa Kubecost con Helm
helm repo add kubecost https://kubecost.github.io/cost-analyzer/
helm repo update
helm install kubecost kubecost/cost-analyzer \
--namespace kubecost \
--create-namespace \
--set kubecostToken="your-token-here" \
--set prometheus.enabled=true \
--set grafana.enabled=true \
--set global.prometheus.enabled=false \
--set global.prometheus.fqdn="http://prometheus.monitoring.svc:9090"
# Port-forward per accedere alla UI
kubectl port-forward svc/kubecost-cost-analyzer 9090:9090 -n kubecost &
# Apri: http://localhost:9090
# Alternativa open-source senza token: OpenCost
helm install opencost opencost/opencost \
--namespace opencost \
--create-namespace
팀에 대한 지불 거절 구성
# Kubecost usa i label Kubernetes per il cost allocation
# Configura label standard per tutti i workload:
# Nel values.yaml di ogni applicazione (Helm):
podLabels:
team: "team-alpha"
cost-center: "CC-2024-ENG"
environment: "production"
product: "checkout-service"
# Kubecost mostra automaticamente i costi aggregati per questi label.
# Es: costo totale team-alpha nel mese = CPU + Memoria + Storage + GPU + Networking
# API Kubecost per report automatici (da inviare via email settimanale):
curl "http://kubecost:9090/model/allocation?window=7d&aggregate=label:team&accumulate=true" \
| jq '.data[0] | to_entries[] | {team: .key, cost: .value.totalCost}'
자동 크기 조정을 위한 VPA
Il 수직형 포드 자동 확장 처리(VPA) 과거 CPU 소비량을 분석하고
포드 메모리를 사용하고 최적의 요청을 계산합니다. 모드 중 Off (권장
자동 적용 없음)은 규모 조정을 위한 가장 안전한 도구입니다.
중단 위험 없이 정확한 숫자를 제공합니다.
# Installa VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh
# Oppure con Helm
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm install vpa fairwinds-stable/vpa \
--namespace vpa \
--create-namespace
---
# vpa-recommendation.yaml - modalita Off: solo raccomandazioni
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-service-vpa
namespace: team-alpha
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-service
updatePolicy:
updateMode: "Off" # non applica automaticamente, solo raccomanda
resourcePolicy:
containerPolicies:
- containerName: api
minAllowed:
cpu: 50m
memory: 64Mi
maxAllowed:
cpu: "4"
memory: 8Gi
# Leggi le raccomandazioni dopo 24-48 ore:
kubectl describe vpa api-service-vpa -n team-alpha
# Output:
# Container Recommendations:
# Container Name: api
# Lower Bound:
# Cpu: 120m
# Memory: 256Mi
# Target: <-- usa questi valori nelle requests
# Cpu: 250m
# Memory: 512Mi
# Upper Bound:
# Cpu: 800m
# Memory: 1500Mi
# Uncapped Target:
# Cpu: 230m
# Memory: 480Mi
대량 규모 조정 분석을 위한 스크립트
# Trova tutti i Deployment con requests > 2x il consumo reale
kubectl get vpa -A -o json | jq -r '
.items[] |
.metadata.namespace + "/" + .metadata.name + ": " +
(.status.recommendation.containerRecommendations[]? |
"target CPU=" + .target.cpu + " Mem=" + .target.memory)
'
# Script bash per generare report di rightsizing
#!/bin/bash
echo "=== Rightsizing Recommendations ==="
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
echo "--- Namespace: $ns ---"
kubectl get vpa -n "$ns" -o custom-columns=\
"NAME:.metadata.name,\
TARGET-CPU:.status.recommendation.containerRecommendations[0].target.cpu,\
TARGET-MEM:.status.recommendation.containerRecommendations[0].target.memory" \
2>/dev/null
done
Karpenter: 통합 및 스팟 인스턴스
Karpenter는 두 가지 방향에서 비용을 최적화합니다. 스팟 인스턴스 에 대한 노드당 비용을 60-70% 절감합니다. 노드를 통합하다 삭제하다 활용도가 낮은 것(빈 패킹).
스팟 + 통합이 포함된 NodePool
# karpenter-cost-optimized.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: cost-optimized
spec:
template:
spec:
nodeClassRef:
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
name: default
requirements:
# Tipi di istanza ottimali per bin-packing (diverse size)
- key: node.kubernetes.io/instance-type
operator: In
values:
- m7i.xlarge # 4 vCPU, 16GB ~$0.20/h on-demand, ~$0.05/h spot
- m7i.2xlarge # 8 vCPU, 32GB
- m7i.4xlarge # 16 vCPU, 64GB
- m7i.8xlarge # 32 vCPU, 128GB
- c7i.2xlarge # CPU-optimized per workload compute-intensive
- r7i.2xlarge # Memory-optimized per carichi con alta RAM
# Mix spot e on-demand con peso
- key: karpenter.sh/capacity-type
operator: In
values:
- spot # priorita spot (economico)
- on-demand # fallback on-demand
disruption:
consolidationPolicy: WhenUnderutilized
consolidateAfter: 1m # consolida subito i nodi sottoutilizzati
limits:
cpu: "1000" # max 1000 vCPU totali
memory: "4000Gi" # max 4TB RAM totale
---
# Configurazione spot interruption handler
# Necessario per gestire le interruzioni spot (AWS invia 2 min di preavviso)
helm install aws-node-termination-handler \
eks/aws-node-termination-handler \
--namespace kube-system \
--set enableSqsTerminationDraining=true \
--set queueURL=https://sqs.eu-west-1.amazonaws.com/123456789/NodeTerminationHandler
Karpenter를 통한 절감 분석
# Verifica quale percentuale dei nodi sono spot
kubectl get nodes -o json | jq '
[.items[] |
{type: .metadata.labels["karpenter.sh/capacity-type"],
instance: .metadata.labels["node.kubernetes.io/instance-type"]}
] |
group_by(.type) |
map({type: .[0].type, count: length})'
# Output esempio:
# [{"type": "on-demand", "count": 3}, {"type": "spot", "count": 12}]
# 80% dei nodi sono spot -> risparmio medio 65% = -$2400/mese
# Kubecost: visualizza costo spot vs on-demand storicamente
# Vai in Cost Allocation > Filter by node type
네임스페이스 예산: FinOps 도구로서의 ResourceQuota
ResourceQuota는 기술적 격리만을 위한 것이 아니라 도구이기도 합니다. 금융 거버넌스의. 예산에 따라 할당량을 할당함으로써 다음과 같은 시스템을 구축할 수 있습니다. 팀이 최적화하도록 유도하는 인센티브:
# budget-quota-team.yaml
# Calcola le quote basandoti sul budget mensile del team
# Budget: 500 EUR/mese (circa 1500 CPU-hours a 0.033 EUR/CPU-hour)
# Assumendo utilizzo medio 50%: requests max = 2000 CPU-hours / 720 ore = 2.8 vCPU mean
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-budget-quota
namespace: team-alpha
annotations:
finops/monthly-budget-eur: "500"
finops/last-reviewed: "2026-01-15"
finops/owner: "alice@company.com"
spec:
hard:
# Basato su budget EUR/mese
requests.cpu: "6" # ~500 EUR/mese a tasso medio spot
requests.memory: "12Gi" # proporzionale
requests.storage: "200Gi"
---
# Alert quando il team si avvicina al budget
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: finops-budget-alerts
namespace: monitoring
spec:
groups:
- name: finops
rules:
- alert: TeamBudgetUsageHigh
expr: |
kubecost_namespace_allocation_cpu_cost_hourly * 24 * 30 +
kubecost_namespace_allocation_memory_cost_hourly * 24 * 30 > 400
for: 1h
labels:
severity: warning
annotations:
summary: "Team {{ $labels.namespace }}: costo mensile proiettato > 400 EUR"
다양한 워크로드에 대한 절약 전략
| 워크로드 유형 | 전략 | 예상 절감액 |
|---|---|---|
| 웹 API(상태 비저장) | 스팟 + HPA + 크기 조정 VPA | 50-65% |
| ML 일괄 작업 | 스팟 + 체크포인트 + scale-to-0 | 60-70% |
| 데이터베이스(상태 저장) | 주문형 예약 + 크기 조정 | 20-30% |
| CI/CD 실행자 | 스팟 + 스케일 투 제로(KEDA) | 70-80% |
| 연중무휴 24시간 중요 서비스 | 예약 인스턴스 + 크기 조정 | 30-40% |
KEDA + Spot을 통한 CI/CD 작업 최적화
# Runners CI/CD sono idle la maggior parte del tempo:
# scala a 0 quando non ci sono job, usa spot
# KEDA ScaledJob per runner GitHub Actions
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
name: github-actions-runner
namespace: actions-runners
spec:
jobTargetRef:
template:
spec:
containers:
- name: runner
image: summerwind/actions-runner:latest
resources:
limits:
cpu: "2"
memory: "4Gi"
nodeSelector:
karpenter.sh/capacity-type: spot # usa spot per runners
tolerations:
- key: "spot"
operator: "Exists"
effect: "NoSchedule"
pollingInterval: 30
minReplicaCount: 0 # scala a 0 quando nessun job
maxReplicaCount: 20 # massimo 20 runner paralleli
triggers:
- type: github-runner
metadata:
owner: "myorg"
repos: "myrepo"
targetWorkflowQueueLength: "1"
Grafana를 사용한 FinOps 대시보드
# PromQL queries per dashboard FinOps Kubernetes
# Costo orario totale del cluster
sum(
kube_pod_container_resource_requests{resource="cpu"} * 0.033 +
kube_pod_container_resource_requests{resource="memory"} / 1073741824 * 0.004
) by (namespace)
# Efficienza CPU per namespace (utilizzo reale / requested)
sum(rate(container_cpu_usage_seconds_total[5m])) by (namespace) /
sum(kube_pod_container_resource_requests{resource="cpu"}) by (namespace) * 100
# Pod con requests molto piu alte del consumo reale (spreco > 70%)
(
kube_pod_container_resource_requests{resource="cpu"} -
rate(container_cpu_usage_seconds_total[24h])
) / kube_pod_container_resource_requests{resource="cpu"} > 0.7
# Importa il dashboard Grafana Kubecost: ID 11270
Kubernetes를 위한 FinOps 모범 사례
월간 FinOps 체크리스트
- VPA 권장사항을 검토하세요. VPA 권장 사항을 분석하고 상위 10개 폐기물에 적정 규모 적용
- 유휴 노드를 확인합니다. 24시간 동안 CPU 및 메모리 사용량이 10% 미만인 노드는 종료되어야 합니다(Karpenter는 이 작업을 자동으로 수행함).
- 스팟 적용 범위를 확인하세요. 목표는 스팟 인스턴스의 비상태 저장 노드의 70-80%입니다.
- 지불 거절 보고서: Kubecost API → 이메일 또는 Slack을 통해 팀당 월별 비용 보고서 보내기
- ResourceQuota 검토: 기본이 아닌 비즈니스 타당성을 위해서만 할당량을 늘리세요.
- 개발 환경을 위한 Scale-to-0: 업무 시간 외에는 개발 환경을 종료해야 합니다(비용 -65%).
결론 및 다음 단계
Kubernetes용 FinOps는 일회성 최적화가 아니라 지속적인 프로세스입니다. 가시성(Kubecost), 지능형 추천(VPA), 효율적인 프로비저닝이 필요합니다. (상업용 Karpenter) 및 조직 거버넌스(예산으로서의 ResourceQuota). 구현 이러한 모든 기술을 함께 사용하면 조직은 일반적으로 처음 3~6개월 동안 Kubernetes 클라우드 청구액의 35~55%를 절감하세요.
다음 단계는 FinOps Kubernetes를 개발 주기에 통합하는 것입니다. 프로덕션에 병합하기 전에 예상 배포 비용을 확인해야 합니다. 비용에 "왼쪽 이동" 접근 방식이 적용됩니다.







