Kubernetes Kosten Optimalisatie in 2026: Right-sizing, Autoscaling en Spot Instances voor EKS, AKS en GKE

Bespaar 30-70% op Kubernetes-kosten met right-sizing, VPA, autoscaling, spot instances en FinOps-tools. Praktische gids met werkende YAML-configs voor EKS, AKS en GKE.

Waarom Kubernetes Kostenoptimalisatie in 2026 Écht Onmisbaar Is

Kubernetes is inmiddels dé standaard voor containerorkestratie — daar hoef ik niemand meer van te overtuigen. Maar die dominantie heeft een flinke keerzijde: exploderende cloudkosten. Recente branchegegevens laten zien dat meer dan 68% van de organisaties 20 tot 40% te veel uitgeeft aan Kubernetes. Voornamelijk door misconfiguraties en een gebrek aan doorlopend kostenbeheer. Eerlijk gezegd is dat een behoorlijk pijnlijk getal.

Het kernprobleem? Een diepgewortelde cultuur van defensieve overprovisioning. Niemand wil degene zijn die verantwoordelijk is voor een storing, dus worden resources standaard ruim ingesteld — vaak drie keer hoger dan het werkelijke verbruik. Het resultaat is voorspelbaar: 31% van de IT-leiders meldt dat meer dan de helft van hun clouduitgaven wordt verspild.

Bij de meeste clusters ligt het daadwerkelijke gebruik tussen slechts 30 en 50% van de beschikbare capaciteit. Dat is alsof je een bus huurt voor drie passagiers.

Goed, laten we daar iets aan doen. In deze gids laat ik zien hoe je met bewezen technieken — right-sizing, autoscaling, spot instances en FinOps-tooling — 30 tot 70% kunt besparen op je Kubernetes-uitgaven. Alle voorbeelden werken op AWS EKS, Azure AKS en Google GKE.

Right-sizing: Veruit de Belangrijkste Besparingshefboom

Right-sizing is en blijft de nummer één besparingsstrategie voor Kubernetes, en dat is niet zonder reden. Het principe is simpel: stel resource requests en limits in die overeenkomen met het werkelijke verbruik, niet met worst-case scenario's.

Kubernetes plant pods op basis van gevraagde resources, niet wat er daadwerkelijk wordt gebruikt. Wanneer pods twee of drie keer meer CPU en geheugen aanvragen dan ze nodig hebben, lijken nodes "vol" terwijl de werkelijke belasting minimaal is. Zonde, toch?

Pod-niveau Right-sizing: Requests en Limits Correct Instellen

De gouden regel hier: baseer je CPU- en geheugen-requests op p95-gebruiksdata over minimaal twee weken, maar idealiter een volledige maand. Zo vang je piekmomenten, batchjobs en onverwachte pieken op. Zelfs een bescheiden 5 tot 15% reductie per pod kan door betere bin-packing resulteren in 30 tot 60% besparing op clusterniveau. Dat klinkt bijna te mooi om waar te zijn, maar ik heb het in de praktijk keer op keer zien werken.

Begin met het verzamelen van actuele gebruiksgegevens met kubectl top:

# Bekijk het huidige resource-gebruik van alle pods in een namespace
kubectl top pods -n production --sort-by=memory

# Vergelijk requests vs. daadwerkelijk gebruik voor een specifieke pod
kubectl get pod mijn-app-pod -n production -o jsonpath='{
  "requests": {
    "cpu": "{.spec.containers[0].resources.requests.cpu}",
    "memory": "{.spec.containers[0].resources.requests.memory}"
  }
}'

# Bekijk node-niveau gebruik om overprovisioning te identificeren
kubectl top nodes

Een praktisch voorbeeld van goed geconfigureerde resources voor een typische webapplicatie:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-api
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-api
  template:
    metadata:
      labels:
        app: web-api
    spec:
      containers:
      - name: api
        image: mijn-registry/web-api:latest
        resources:
          requests:
            cpu: "250m"      # Gebaseerd op p95 CPU-gebruik
            memory: "512Mi"  # Gebaseerd op p95 geheugengebruik
          limits:
            cpu: "1000m"     # 4x headroom voor pieken
            memory: "1Gi"    # 2x headroom, voorkomt OOMKill

Pro-tip: Overweeg om CPU-limits helemaal weg te laten voor niet-kritieke workloads. CPU-limits veroorzaken throttling, zelfs als er vrije CPU beschikbaar is op de node. Zonder die limits kan je applicatie pieken opvangen met ongebruikte capaciteit — wat zowel prestaties als efficiëntie verbetert. Win-win.

Node-niveau Right-sizing: Kies het Juiste Instance-type

Niet alleen pods verdienen aandacht. Het type node maakt ook een groot verschil. Gebruik memory-geoptimaliseerde instances (zoals AWS r-serie of Azure E-serie) voor in-memory databases en caches, en compute-geoptimaliseerde instances (c-serie) voor CPU-intensieve analytics. Het migreren van een general-purpose instance naar een gespecialiseerd type levert vaak directe besparingen op zonder dat je verder iets hoeft te wijzigen.

Vertical Pod Autoscaler (VPA): Automatisch Right-sizing

Handmatig right-sizing is arbeidsintensief en schaalt simpelweg niet. Als je tientallen (of honderden) deployments hebt, ga je dat niet allemaal met de hand bijhouden. De Vertical Pod Autoscaler (VPA) automatiseert dit proces door het werkelijke resourceverbruik van pods te monitoren en automatisch CPU- en geheugen-requests aan te passen.

VPA Installeren

De snelste manier om VPA te installeren is via Helm:

# VPA installeren via Helm
helm repo add cowboysysop https://cowboysysop.github.io/charts/
helm install vpa cowboysysop/vertical-pod-autoscaler \
  --namespace kube-system

# Controleer of alle drie de VPA-componenten draaien
kubectl get pods -n kube-system | grep vpa

VPA bestaat uit drie componenten: de Recommender (analyseert gebruik en berekent aanbevelingen), de Updater (verwijdert pods die aangepast moeten worden) en de Admission Controller (past aanbevelingen toe op nieuwe pods bij het aanmaken). Klinkt complex, maar in de praktijk werkt het vrij naadloos samen.

Stap 1: Start met Off-modus (Doe Dit Altijd Eerst)

Begin áltijd in Off-modus. VPA berekent dan aanbevelingen zonder iets te wijzigen — perfect om eerst te begrijpen wat er nodig is voordat je automatisch gaat schalen:

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: web-api-vpa
  namespace: production
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: web-api
  updatePolicy:
    updateMode: "Off"  # Alleen aanbevelingen, geen wijzigingen

Bekijk de aanbevelingen na een paar dagen:

# VPA-aanbevelingen ophalen
kubectl describe vpa web-api-vpa -n production

# Output toont:
# Target:     cpu: 180m,  memory: 420Mi  (aanbevolen)
# Lower Bound: cpu: 100m, memory: 300Mi  (minimum)
# Upper Bound: cpu: 500m, memory: 800Mi  (maximum)

Stap 2: Schakel Over naar Auto-modus

Wanneer je vertrouwen hebt in de aanbevelingen (en dat kost even, dat snap ik), schakel je over naar Auto-modus met veilige grenzen:

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: web-api-vpa
  namespace: production
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: web-api
  updatePolicy:
    updateMode: "Auto"
    minReplicas: 2  # Houd minimaal 2 replica's actief tijdens updates
  resourcePolicy:
    containerPolicies:
    - containerName: api
      minAllowed:
        cpu: 50m
        memory: 128Mi
      maxAllowed:
        cpu: 2
        memory: 4Gi
      controlledResources:
      - cpu
      - memory
      controlledValues: RequestsAndLimits

Belangrijk om te weten: VPA in Auto-modus herstart pods om nieuwe resource-waarden toe te passen. Dat is niet ideaal in productie. Maar goed nieuws: sinds Kubernetes 1.27+ met VPA 1.2+ is in-place pod resizing beschikbaar, waardoor pods hun resources kunnen aanpassen zónder herstart. Een echte doorbraak voor productieomgevingen.

Horizontale en Cluster Autoscaling: Schaal Mee met de Vraag

Waar VPA individuele pods optimaliseert, zorgen Horizontal Pod Autoscaler (HPA) en cluster autoscaling ervoor dat het totale aantal pods én nodes meebeweegt met de werkelijke vraag.

De combinatie is cruciaal. Zonder cluster autoscaling betaal je voor lege nodes. Zonder HPA vallen pods om onder piekbelasting. Beide scenario's wil je vermijden.

HPA Configureren voor Kostenefficiëntie

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-api-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70  # Schaal op bij 70% CPU-gebruik
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300  # Wacht 5 min voor downscaling
      policies:
      - type: Percent
        value: 25          # Maximaal 25% minder pods per keer
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
      - type: Percent
        value: 100         # Verdubbel pods indien nodig
        periodSeconds: 60

De scaleDown-configuratie is essentieel voor kostenbesparing. Die stabilisatieperiode van 5 minuten voorkomt flapping (herhaaldelijk op- en afschalen), terwijl het maximale afschalingspercentage van 25% zorgt voor een geleidelijke afbouw. Ik heb teams gezien die zonder deze instellingen onnodig heen en weer schaalden — duur én stressvol.

Karpenter vs. Cluster Autoscaler: Welke Kiezen?

Voor cluster-niveau autoscaling heb je twee opties: de traditionele Cluster Autoscaler en het nieuwere Karpenter (oorspronkelijk voor AWS, nu ook beschikbaar voor Azure). De verschillen in kostenbesparing zijn best aanzienlijk:

  • Karpenter kiest dynamisch het goedkoopste passende instance-type per pod, ondersteunt automatische consolidatie van onderbenutde nodes, en teams rapporteren gemiddeld 20% clusterwijde kostenreductie (en tot 90% op CI/CD-workloads). Het provisioned nodes via de EC2 Fleet API in circa 55 seconden.
  • Cluster Autoscaler werkt met voorgedefinieerde node-groepen van vaste grootte, evalueert slechts één node tegelijk voor downscaling en heeft 3-4 minuten nodig om nieuwe nodes op te starten. Betrouwbaar, maar duurder door het gebrek aan proactieve optimalisatie.

Mijn advies: Kies Karpenter voor dynamische, cloud-native omgevingen (met name op AWS). De Cluster Autoscaler blijft een goede keuze voor multi-cloud setups, stabiele workloads of GPU-intensieve ML-taken.

Spot Instances: Tot 90% Besparing op Compute

Spot instances (AWS), Spot VMs (Azure) en Preemptible VMs (GCP) bieden 60 tot 90% korting ten opzichte van on-demand prijzen. Ja, je leest dat goed — tot 90%. In 2026 is de interruption-handling zodanig verbeterd dat spot instances een realistische optie zijn voor veel meer workloads dan voorheen.

Spot Node Pools Configureren per Cloud Provider

AWS EKS met Karpenter:

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: spot-workloads
spec:
  template:
    spec:
      requirements:
      - key: karpenter.sh/capacity-type
        operator: In
        values: ["spot"]          # Gebruik spot instances
      - key: node.kubernetes.io/instance-type
        operator: In
        values:                    # Diversificeer over meerdere types
        - m5.large
        - m5.xlarge
        - m6i.large
        - m6i.xlarge
        - c5.large
        - c5.xlarge
      nodeClassRef:
        group: karpenter.k8s.aws/v1
        kind: EC2NodeClass
        name: default
  limits:
    cpu: "100"
    memory: 400Gi
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 60s

Azure AKS Spot Node Pool:

# Spot node pool toevoegen aan bestaand AKS-cluster
az aks nodepool add \
  --resource-group mijn-rg \
  --cluster-name mijn-aks-cluster \
  --name spotpool \
  --priority Spot \
  --eviction-policy Delete \
  --spot-max-price -1 \
  --node-count 3 \
  --min-count 1 \
  --max-count 10 \
  --enable-cluster-autoscaler \
  --node-vm-size Standard_D4s_v5 \
  --labels workload-type=spot-tolerant

Google GKE Spot Node Pool:

# Spot node pool toevoegen aan GKE-cluster
gcloud container node-pools create spot-pool \
  --cluster=mijn-gke-cluster \
  --zone=europe-west4-a \
  --spot \
  --num-nodes=3 \
  --min-nodes=1 \
  --max-nodes=10 \
  --enable-autoscaling \
  --machine-type=e2-standard-4 \
  --node-labels=workload-type=spot-tolerant

Workloads Geschikt Maken voor Spot Instances

Niet elke workload is geschikt voor spot — dat is belangrijk om te beseffen. Gebruik taints en tolerations om te garanderen dat alleen geschikte workloads op spot nodes terechtkomen:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: batch-processor
  namespace: batch
spec:
  replicas: 5
  selector:
    matchLabels:
      app: batch-processor
  template:
    metadata:
      labels:
        app: batch-processor
    spec:
      tolerations:
      - key: "kubernetes.azure.com/scalesetpriority"
        operator: "Equal"
        value: "spot"
        effect: "NoSchedule"
      nodeSelector:
        workload-type: spot-tolerant
      terminationGracePeriodSeconds: 120  # Geef pods tijd om af te ronden
      containers:
      - name: processor
        image: mijn-registry/batch-processor:latest
        resources:
          requests:
            cpu: "500m"
            memory: "1Gi"

Ideale workloads voor spot instances: CI/CD-pipelines, batchverwerking, ML-trainingsjobs, stateless webservices en event-driven taken. Vermijd spot voor: stateful applicaties, databases en latency-kritieke services. Kortom, als het pijn doet wanneer je pod ineens verdwijnt, gebruik dan geen spot.

Kostenvergelijking per Provider (2026)

KenmerkAWS EKSAzure AKSGoogle GKE
Control plane kosten$0,10/uur/clusterGratis (Free tier)Management fee
Spot besparing60-90%60-90%60-90%
Reserved Instance besparingTot 75%Tot 72% (3 jaar)Tot ~70% (CUDs)
Node autoscalerKarpenter / CACluster Autoscaler / Karpenter (preview)Cluster Autoscaler

FinOps-tooling: Zichtbaarheid als Fundament

Je kunt niet optimaliseren wat je niet kunt meten — dat klinkt als een open deur, maar het is verbazingwekkend hoe vaak dit over het hoofd wordt gezien. De abstractielaag van Kubernetes maakt kostentoerekening complex. De cloudfactuur toont slechts de totaalkosten van nodes, niet het verbruik per pod, service of team.

FinOps-tools doorbreken deze "financiële black box".

OpenCost: De Gratis Open-source Standaard

OpenCost is een CNCF incubating project dat real-time kostentoerekening biedt per cluster, node, namespace, controller en pod. Het is volledig open-source (Apache 2.0) en ondersteunt AWS, Azure en GCP.

# OpenCost installeren via Helm
helm repo add opencost https://opencost.github.io/opencost-helm-chart
helm install opencost opencost/opencost \
  --namespace opencost \
  --create-namespace \
  --set opencost.prometheus.internal.enabled=true

# Kosten per namespace opvragen via de API
kubectl port-forward -n opencost svc/opencost 9090:9090 &
curl -s "http://localhost:9090/allocation/compute?window=7d&aggregate=namespace" \
  | python3 -m json.tool

Eerlijk gezegd heeft OpenCost wel beperkingen: het houdt geen rekening met kortingen, spot-pricing of credits. Er is geen multi-cluster aggregatie out-of-the-box en geen automatische optimalisatie. Maar als gratis startpunt voor teams die hun eigen observability-stack opbouwen? Dan is het uitstekend.

Kubecost: Enterprise-grade Kostenbeheer

Kubecost (inmiddels onderdeel van IBM) bouwt voort op OpenCost en voegt discount-reconciliatie, multi-cluster support, budgetalerts en right-sizing aanbevelingen toe. De gratis tier is prima voor kleine clusters, maar wees gewaarschuwd: de kosten stijgen snel bij schaalvergroting. Sommige teams rapporteren meer dan $70.000 per jaar voor het monitoren van slechts drie clusters. Dat is nogal wat.

ResourceQuotas: Governance op Namespaceniveau

Wil je voorkomen dat teams onbeperkt resources claimen? Gebruik dan ResourceQuotas en LimitRanges:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-frontend-quota
  namespace: frontend
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    pods: "50"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: frontend
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    type: Container

De LimitRange zorgt ervoor dat elke container die zonder expliciete resources wordt gedeployed automatisch verstandige standaardwaarden krijgt. Een simpele maar effectieve bescherming tegen onbewuste overprovisioning.

Een Compleet Optimalisatieplan in Vijf Stappen

Het FinOps-framework beschrijft drie fasen: Inform (zichtbaarheid), Optimize (handelen) en Operate (automatiseren). Hieronder een praktisch vijfstappenplan dat je direct kunt toepassen:

  1. Meet en label alles: Installeer OpenCost of Kubecost. Dwing een strikt labelbeleid af (team, project, kostenplaats) zodat elke resource traceerbaar is. Zonder labels ben je blind.
  2. Right-size pods: Deploy VPA in Off-modus, verzamel twee weken data, pas requests aan op basis van p95-waarden. Verwijder CPU-limits waar dat veilig kan.
  3. Implementeer autoscaling: Configureer HPA voor horizontale elasticiteit en Karpenter (of Cluster Autoscaler) voor node-niveau schaling. Stel agressieve scale-down policies in — dit is waar het grote geld zit.
  4. Introduceer spot instances: Creëer spot node pools voor niet-kritieke workloads (batch, CI/CD, stateless services). Diversificeer over meerdere instance-types voor maximale beschikbaarheid.
  5. Automatiseer governance: Stel ResourceQuotas in per namespace, configureer budgetalerts en review kosten wekelijks in standoverleggen. Voer elk kwartaal een diepgaande kostenanalyse uit.

Veelgestelde Vragen

Hoe detecteer ik of mijn Kubernetes-cluster overprovisioned is?

Als je cluster minder dan 50% van de beschikbare resources (CPU en geheugen) benut, is dat een sterk signaal van overprovisioning. Gebruik kubectl top nodes voor een snelle check, of installeer OpenCost voor gedetailleerder inzicht. Uit audits in 2026 blijkt dat 80 tot 90% van de pods te hoge CPU- en geheugen-requests heeft ingesteld.

Kan ik VPA en HPA tegelijkertijd gebruiken?

Ja, dat kan — maar met een belangrijke voorwaarde. Laat VPA de CPU- en geheugen-requests per pod optimaliseren en HPA het aantal replica's schalen op basis van een custom metric (zoals requests per seconde). Vermijd dat beide op dezelfde metric sturen (bijvoorbeeld CPU-percentage), want dat veroorzaakt conflicten en onvoorspelbaar gedrag.

Zijn spot instances betrouwbaar genoeg voor productie?

Voor stateless workloads: absoluut. In 2026 is de interruption-handling sterk verbeterd. Tools zoals Karpenter detecteren spot-terminatienotificaties twee minuten van tevoren en verplaatsen pods proactief naar stabiele nodes. Combineer spot met on-demand nodes en gebruik pod disruption budgets voor maximale beschikbaarheid.

Hoe vaak moet ik Kubernetes-kosten reviewen?

De beste aanpak is continue geautomatiseerde monitoring met kwartaalmatige diepgaande reviews. Geautomatiseerde tools identificeren doorlopend verspilling. Platformteams bespreken kostentrends wekelijks in standoverleggen. Elk kwartaal analyseer je grotere patronen en pas je reserved instance-commitments aan.

Vanaf welke clustergrootte loont kostenoptimalisatie?

Het kantelpunt ligt doorgaans bij $10.000 tot $20.000 maandelijkse uitgaven, wat correspondeert met zo'n 20-50 nodes of 100-200 pods. Onder dit niveau is de investering in tooling en processen vaak groter dan de besparing. Maar basispraktijken zoals het instellen van resource requests en het activeren van cluster autoscaling? Die lonen altijd, ongeacht de schaal.

Over de Auteur Editorial Team

Our team of expert writers and editors.