FinOps pentru Kubernetes: dimensionare drepturi, instanțe spot și reducere a costurilor
68% dintre organizațiile care folosesc Kubernetes în producție cheltuiesc cu 20-40% mai mult decât este necesar (CNCF Cost Survey 2026). Nu pentru că Kubernetes este ineficient, ci pentru că aprovizionarea generoasă și ușoară, iar dimensionarea corectă necesită disciplină operațională. The rezultat și cluster cu utilizarea medie a procesorului la 15-20% și memorie la 30-40%: resurse plătite dar nu folosi.
FinOps pentru Kubernetes și practica de măsurare, optimizare și guvernare cheltuieli de cluster. În acest articol vom vedea cum se utilizează Kubecost pentru vizibilitatea costurilor pentru spațiile de nume, cum ar fi VPA ajută la corectarea cereri automate, cum Karpenter optimizează nodul bin-packing cu instanțe spot și ce politici să implementeze la nivel organizațional pentru a menține costurile sub control în timp.
Ce vei învăța
- Instalați și configurați Kubecost pentru vizibilitatea costurilor spațiului de nume/echipelor
- VPA în modul Oprit: recomandări automate de dimensionare a dreptului fără întreruperi
- Karpenter: Consolidare pentru o ambalare optimă a nodurilor
- Localizați instanțe pe AWS/GCP/Azure cu Karpenter și gestionați întreruperi
- ResourceQuota ca instrument de bugetare a echipei
- Alertă Prometheus pentru deșeuri și anomalii de cost
- Cum să construiți un sistem de rambursare pentru echipe
- Benchmark: economii reale realizabile cu fiecare tehnică
De ce Kubernetes tinde să fie supraprovizionat
Înainte de optimizare, trebuie să înțelegeți cauzele problemei:
- Cereri conservatoare: Echipele au stabilit cererile la un nivel ridicat „pentru a fi în siguranță” (de exemplu, 1 CPU pentru o aplicație care utilizează 0.1). Cererile determină numărul de noduri necesare
- Limite = cereri: Multe șabloane CI/CD stabilesc limite egale cu cererile, creând supraprovizionare sistematică
- Spații de nume goale: Spațiu de nume de dezvoltare cu poduri „Hello World” care rămân 24/7
- Noduri supradimensionate: Instanțe de cloud mari cu împachetare ineficientă (un pod cu 2 vCPU pe un nod cu 32 vCPU)
- Fără vizibilitate pentru echipe: Dacă echipele nu văd costul lor, nu au niciun stimulent să optimizeze
Kubecost: Vizibilitatea costurilor spațiilor de nume
Kubecost Este cel mai folosit instrument FinOps din ecosistemul Kubernetes. Colectează valori de la Prometheus, preia prețurile instanțelor cloud (AWS, GCP, Azure) și calculați costul alocat pentru spațiu de nume, implementare, cont de serviciu și etichetă.
Instalare Kubecost
# 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
Configurați Chargeback pentru echipe
# 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 pentru dimensionarea automată a drepturilor
Il Vertical Pod Autoscaler (VPA) analizează consumul istoric al CPU și
Memorie pod și calculează cererile optime. În modul Off (recomandare
fără aplicare automată) este cel mai sigur instrument de dimensionare în drepturi: oferă
numere precise fără risc de perturbare.
# 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
Script pentru analiza dimensionării în vrac
# 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: Instanțe de consolidare și spot
Karpenter optimizează costurile din două direcții: utilizare instanțe la vedere pentru reduce costul per nod cu 60-70%, de ex consolidarea nodurilor a sterge cele subutilizate (bin-packing).
NodePool cu Spot + Consolidare
# 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
Analiza economiilor cu 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
Buget al spațiului de nume: ResourceQuota ca instrument FinOps
Cotele de resurse nu sunt doar pentru izolare tehnică, ci sunt și un instrument a guvernanței financiare. Prin atribuirea de cote pe baza bugetelor, creați un sistem de stimulente care împing echipele să optimizeze:
# 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"
Strategii de economisire pentru diferite sarcini de lucru
| Tipul sarcinii de lucru | Strategie | Economii așteptate |
|---|---|---|
| API web (apatrid) | Spot + HPA + corectare VPA | 50-65% |
| Locuri de lucru ML | Spot + punct de control + scară la zero | 60-70% |
| Baze de date (cu stare) | Rezervat la cerere + dimensionare drepturi | 20-30% |
| alergători CI/CD | Spot + scalare la zero (KEDA) | 70-80% |
| Servicii critice 24/7 | Instanțe rezervate + dimensionare drepturi | 30-40% |
Optimizarea lucrărilor CI/CD cu KEDA + Spot
# 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"
Tabloul de bord FinOps cu Grafana
# 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
Cele mai bune practici FinOps pentru Kubernetes
Lista de verificare lunară FinOps
- Examinați recomandările VPA: Analizați recomandările APV și aplicați dimensionarea corectă în Top 10 deșeuri
- Verificați nodurile inactive: Nodurile cu CPU și utilizarea memoriei < 10% timp de 24 de ore trebuie să fie terminate (Karpenter face acest lucru automat)
- Verificați acoperirea spotului: Scopul este 70-80% din nodurile fără stare pe instanțe spot
- Rapoarte de rambursare: Trimiteți un raport lunar de cost pe echipă prin Kubecost API → e-mail sau Slack
- Examinați Cota de resurse: Creșteți cotele doar cu justificare de afaceri, nu implicit
- Scalare la zero pentru mediile de dezvoltare: Mediile de dezvoltare ar trebui să fie închise în afara orelor de lucru (cost -65%)
Concluzii și pașii următori
FinOps pentru Kubernetes nu este o optimizare unică: este un proces continuu care necesită vizibilitate (Kubecost), recomandări inteligente (VPA), aprovizionare eficientă (Karpenter cu guvernanță comercială) și organizațională (ResourceQuota ca buget). Implementarea toate aceste tehnici împreună, organizațiile obțin de obicei economii de 35-55% din factura de cloud Kubernetes în primele 3-6 luni.
Următorul pas este integrarea FinOps Kubernetes în ciclul de dezvoltare: dezvoltatorii ar trebui să vadă costul estimat al implementării lor înainte de fuzionarea în producție — o abordare „deplasare la stânga” aplicată costurilor.







