FinOps pro Kubernetes: Rightsizing, okamžité instance a snížení nákladů
68 % organizací využívajících Kubernetes v produkci utrácí o 20–40 % více než je nutné (CNCF Cost Survey 2026). Ne proto, že by Kubernetes byl neefektivní, ale protože velkorysé a snadné poskytování a přidělování práv vyžaduje provozní disciplínu. The výsledek a cluster s průměrným využitím procesoru 15–20 % a pamětí 30–40 %: prostředky zaplaceny ale nepoužívejte.
FinOps pro Kubernetes a praxe měření, optimalizace a řízení klastrové výdaje. V tomto článku uvidíme, jak používat Kubecost pro viditelnost nákladů na jmenné prostory, jako je např VPA pomáhá při úpravě práv automatické požadavky, jak Karpenter optimalizuje balení přihrádek uzlů se spotovými instancemi a jaké zásady implementovat na organizační úrovni pro udržení nákladů časem pod kontrolou.
Co se naučíte
- Nainstalujte a nakonfigurujte Kubecost pro viditelnost jmenného prostoru/týmových nákladů
- VPA ve vypnutém režimu: Automatická doporučení správné velikosti bez přerušení
- Karpenter: Konsolidace pro optimální bin-packing uzlů
- Sledujte instance na AWS/GCP/Azure pomocí Karpenter a správy přerušení
- ResourceQuota jako týmový rozpočtový nástroj
- Upozorněte Promethea na plýtvání a anomálie nákladů
- Jak vytvořit systém zpětného zúčtování pro týmy
- Benchmark: skutečné úspory dosažitelné s každou technikou
Proč má Kubernetes tendenci být overprovisioned
Před optimalizací musíte pochopit příčiny problému:
- Konzervativní požadavky: Týmy nastavují požadavky na vysokou hodnotu „aby byly bezpečné“ (např. 1 CPU pro aplikaci, která používá 0,1). Požadavky určují počet potřebných uzlů
- Limity = požadavky: Mnoho šablon CI/CD nastavuje limity rovné požadavkům, což vytváří systematické nadměrné poskytování
- Prázdné jmenné prostory: Vývojový jmenný prostor s moduly „Hello World“, které zůstávají 24/7
- Nadměrné uzly: Velké cloudové instance s neefektivním bin-packingem (2 vCPU Pod na 32 vCPU uzlu)
- Žádná viditelnost pro týmy: Pokud týmy nevidí své náklady, nemají motivaci k optimalizaci
Kubecost: Viditelnost nákladů na jmenný prostor
Kubecost Je to nejpoužívanější nástroj FinOps v ekosystému Kubernetes. Shromažďuje metriky z Prometheus, získává ceny cloudových instancí (AWS, GCP, Azure) a vypočítat náklady přidělené pro obor názvů, nasazení, servisní účet a štítek.
Instalace 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
Nakonfigurujte Chargeback pro Teams
# 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 pro automatické přizpůsobení velikosti
Il Vertical Pod Autoscaler (VPA) analyzuje historickou spotřebu CPU a
Pod paměť a vypočítá optimální požadavky. V režimu Off (doporučení
bez automatické aplikace) je nejbezpečnějším nástrojem pro přizpůsobení: poskytuje
přesná čísla bez rizika narušení.
# 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
Skript pro hromadnou analýzu správné velikosti
# 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: Konsolidační a bodové instance
Karpenter optimalizuje náklady ze dvou směrů: použití spotové instance pro snížit náklady na uzel o 60-70 %, např konsolidovat uzly smazat nedostatečně využívané (balení do popelnic).
NodePool s Spot + konsolidace
# 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
Analýza úspor s Karpenterem
# 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
Rozpočet jmenného prostoru: ResourceQuota jako nástroj FinOps
ResourceQuotas nejsou jen pro technickou izolaci – jsou také nástrojem finančního řízení. Přiřazením kvót na základě rozpočtů vytvoříte systém pobídky, které tlačí týmy k optimalizaci:
# 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"
Strategie úspor pro různé pracovní zátěže
| Typ pracovní zátěže | Strategie | Očekávané úspory |
|---|---|---|
| Web API (bezstavové) | Spot + HPA + Rightsizing VPA | 50–65 % |
| ML dávkové úlohy | Bod + kontrolní bod + měřítko na nulu | 60–70 % |
| Databáze (stavové) | Vyhrazeno na vyžádání + nastavení práv | 20–30 % |
| CI/CD mechaniky | Bod + stupnice na nulu (KEDA) | 70–80 % |
| Kritické služby 24/7 | Vyhrazené instance + Rightsizing | 30–40 % |
Optimalizace úlohy CI/CD s 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"
Panel FinOps s Grafanou
# 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
FinOps Best Practices pro Kubernetes
Měsíční kontrolní seznam FinOps
- Přečtěte si doporučení VPA: Analyzujte doporučení VPA a aplikujte správné nastavení na 10 nejčastějších odpadů
- Zkontrolujte nečinné uzly: Uzly s využitím CPU a paměti < 10 % po dobu 24 hodin musí být ukončeny (Karpenter to provede automaticky)
- Zkontrolujte pokrytí místa: Cílem je 70–80 % nestavových uzlů na spotových instancích
- Přehledy zpětného zúčtování: Odešlete měsíční výkaz nákladů na tým přes Kubecost API → e-mail nebo Slack
- Zkontrolujte ResourceQuota: Zvyšte kvóty pouze s obchodním odůvodněním, nikoli ve výchozím nastavení
- Měřítko na nulu pro vývojová prostředí: Vývojová prostředí by měla být mimo pracovní dobu vypnuta (náklady -65 %)
Závěry a další kroky
FinOps pro Kubernetes není jednorázová optimalizace: je to pokračující proces, který vyžaduje viditelnost (Kubecost), inteligentní doporučení (VPA), efektivní poskytování (Karpenter s obchodním) a organizačním řízením (ResourceQuota jako rozpočet). Provádění všechny tyto techniky dohromady organizace obvykle dosahují úspor 35–55 % na vašem cloudovém účtu Kubernetes během prvních 3–6 měsíců.
Dalším krokem je integrace FinOps Kubernetes do vývojového cyklu: vývojáři před sloučením do produkce by měli vidět odhadované náklady na jejich nasazení – u nákladů byl aplikován přístup „shift-left“.







