Ik schrijf veel over Kubernetes. Ik draai het dagelijks. Ik vind het oprecht een mooi stuk techniek.

Dus het verbaast je misschien dat ik regelmatig mensen ervan afpraat.

Dit is het scenario waar ik steeds opnieuw inloop. Een klein team, één product, een roadmap vol echte features om te bouwen, en iemand heeft besloten dat de eerste mijlpaal een Kubernetes cluster is. Minimaal drie nodes, etcd, een CNI, een ingress controller, cert-manager, een monitoring stack. Weken werk voordat één klant iets ziet. Iedereen knikt mee, want zo ziet serieuze infrastructuur er nu eenmaal uit in 2026.

Ik wil je de andere kant van dat raam laten zien. Want voor veel teams bestaat er een versie waarin je in een middag live gaat, elk bewegend onderdeel begrijpt, en alsnog prima slaapt.

Deze post is voor iedereen die voor die keuze staat. Niet om je af te schrikken van Kubernetes, maar om je het bewust te laten kiezen in plaats van standaard.

De Kubernetes hype

Kubernetes heeft gewonnen. Het is het standaardantwoord voor container orchestration, elke cloud verkoopt een managed variant, en elke DevOps vacature noemt het. Zodra iets de vanzelfsprekende keuze wordt, stopt men met de vraag of het de juiste keuze is. De tool is dan geen beslissing meer, maar het water waarin je zwemt.

Ik snap de aantrekkingskracht. Ik koos Kubernetes voor mijn eigen homelab heel bewust, en daar heb ik genoeg over geschreven. Maar “iedereen draait het” is de zwakste reden die er is om iets te draaien, zeker infrastructuur die je moet begrijpen als ze om twee uur ’s nachts stukgaat.

Kubernetes verdient zijn complexiteit door een specifieke set problemen op te lossen:

  • Containers orchestreren over meerdere nodes
  • Automatisch schalen op basis van load
  • Self-healing wanneer containers crashen
  • Declaratieve configuratie van infrastructuur
  • Service discovery en load balancing

Lees dat lijstje en wees eerlijk over welke je echt hebt. Heb je alle vijf, dan is Kubernetes een cadeau. Heb je er geen, dan is het pure kosten zonder iets aan de andere kant van de balans. Je betaalt voor capaciteit die je nooit gebruikt, in de munt die je het minst kunt missen: je eigen aandacht.

Wanneer Kubernetes overkill is

Je hebt één applicatie

Eén monoliet. Eén database. Misschien een Redis cache. Draait vandaag prima op één server.

Wat koopt Kubernetes je hier?

Je applicatie → Kubernetes cluster → 3+ nodes → etcd →
control plane → ingress controller → cert-manager →
monitoring stack → ...

Versus:

Je applicatie → Docker Compose → 1 server

Aan beide kanten dezelfde functionaliteit. De bovenste kost je ongeveer tien keer zoveel tijd, geld en cognitieve load om er te komen. De onderste kun je in je hoofd houden.

Je team is klein

Kubernetes vraagt je veel te begrijpen voordat je het veilig kunt draaien. Niet alleen de kern, maar alles eromheen:

  • Networking (CNI, service mesh, ingress)
  • Storage (CSI, persistent volumes)
  • Security (RBAC, network policies, pod security)
  • Observability (metrics, logs, traces)
  • GitOps (ArgoCD, Flux)

Een team van twee of drie developers dat ook de pager draagt heeft de vrije uren niet om dat allemaal te leren en te onderhouden bovenop het bouwen van het eigenlijke product. Er moet iets sneuvelen, en dat zijn meestal je weekenden of je uptime.

Je traffic is voorspelbaar

De pronkfunctie is automatisch schalen. Maar als je traffic stabiel op 100 requests per seconde zit zonder vervelende spikes, lost autoscaling een probleem op dat je niet hebt. Overprovision een beetje, zet een reminder om over een half jaar te herzien, en ga door.

Je budget is beperkt

Managed Kubernetes (EKS, GKE, AKS) is niet gratis, en de posten tellen snel op:

  • Control plane fees (~$70-150/maand)
  • Minimaal 3 worker nodes voor HA
  • Load balancer kosten
  • Persistent volume kosten
  • Egress kosten

Voor één simpele app zit je zo op $300-500 per maand. Dezelfde app draait vrolijk op een $20 VPS. Het verschil is geen capaciteit, het is de tol die je betaalt voor een abstractie die je niet gebruikt.

Je hebt geen microservices

Kubernetes is gebouwd voor microservices: veel kleine, onafhankelijke services die op hun eigen ritme schalen en falen. Een monoliet heeft die behoeften niet. Er een op Kubernetes draaien is als een Ferrari kopen voor de wekelijkse boodschappen. Het werkt, maar elke feature waarvoor je betaalt staat ongebruikt op de oprit.

De verborgen kosten van Kubernetes

De prijs op het kaartje is het makkelijke deel. De kosten die echt pijn doen zijn die welke niet op de factuur verschijnen.

Operationele overhead

Zelfs op managed Kubernetes blijft het cluster een levend ding dat je voor altijd verzorgt:

  • Cluster upgrades (elke 3-4 maanden nieuwe versie)
  • Node pool management
  • Capacity planning
  • Incident response wanneer pods niet starten
  • Debugging networking issues

Dit is gestaag, terugkerend werk, en iemand in het team is er eigenaar van of je dat nu gepland had of niet.

Leercurve

Dit is de woordenschat die je nodig hebt voordat je over een draaiend cluster kunt nadenken:

  • Pods, Deployments, StatefulSets, DaemonSets
  • Services, Ingress, NetworkPolicies
  • ConfigMaps, Secrets
  • PersistentVolumes, StorageClasses
  • RBAC, ServiceAccounts
  • Helm, Kustomize
  • CRDs, Operators

En dat is nog voor de ecosysteem tools die elk echt cluster aanmaakt: Prometheus, Grafana, ArgoCD, cert-manager, external-dns, en nog een stuk of tien. Elk daarvan is weer iets om te leren, te patchen en te begrijpen wanneer het zich misdraagt.

YAML hell

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app:v1.0.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
# ... nog meer YAML

Dat is het minimum om één applicatie draaiend te krijgen. Hier is dezelfde bedoeling in Docker Compose:

services:
  my-app:
    image: my-app:v1.0.0
    ports:
      - "80:8080"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]

Debugging complexiteit

Container start niet? In Docker is het hele onderzoek één regel:

docker logs my-app

In Kubernetes wordt dezelfde vraag een kleine expeditie:

kubectl describe pod my-app-7d9f8b6c5d-x2k9p
kubectl logs my-app-7d9f8b6c5d-x2k9p
kubectl logs my-app-7d9f8b6c5d-x2k9p --previous
kubectl get events --field-selector involvedObject.name=my-app-7d9f8b6c5d-x2k9p

En het antwoord blijkt een ImagePullBackOff door een typo in de image naam. Of een resource limit. Of een volle node. Elke laag die Kubernetes toevoegt is een laag die je doorloopt als je probeert te achterhalen waarom er niets gebeurde. Die tol is onzichtbaar op een goede dag en bruut op een slechte.

Alternatieven voor Kubernetes

Dus als niet Kubernetes, wat dan? Dit is het deel van het raam waar ik je echt naar wil laten kijken. Geen van deze is speelgoed. Elk is een tool waar ik in de juiste situatie naar grijp, en meerdere ervan draaien op dit moment echte productie traffic voor echte bedrijven.

Docker Compose

Wanneer: Eén server, meerdere containers, simpele setup.

services:
  app:
    image: my-app:latest
    ports:
      - "80:8080"
    depends_on:
      - db
      - redis
    environment:
      - DATABASE_URL=postgres://db:5432/app
    restart: unless-stopped

  db:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7
    restart: unless-stopped

volumes:
  postgres_data:

docker compose up -d en je draait. Updates zijn docker compose pull && docker compose up -d. Het hele mentale model past in één bestand dat je van boven naar beneden kunt lezen.

Voordelen:

  • Simpel te begrijpen
  • Geen cluster overhead
  • Werkt overal waar Docker draait
  • Perfecte developer experience

Nadelen:

  • Geen automatisch schalen
  • Geen high availability (single node)
  • Beperkte orchestration

Docker Swarm

Wanneer: Meerdere nodes nodig, maar Kubernetes te complex.

Docker Swarm is het vergeten broertje. Simpeler, minder features, en vaak ruim voldoende.

# Init swarm
docker swarm init

# Deploy stack
docker stack deploy -c docker-compose.yml myapp

# Scale
docker service scale myapp_web=5

Voordelen:

  • Dezelfde Docker Compose files
  • Ingebouwd in Docker
  • Makkelijke setup
  • Multi-node support

Nadelen:

  • Minder ecosysteem
  • Beperkte community (Docker focust op Kubernetes)
  • Minder features dan Kubernetes

HashiCorp Nomad

Wanneer: Je wilt orchestration zonder Kubernetes complexiteit, of je draait meer dan alleen containers.

Nomad is een lightweight alternatief dat containers, VMs en standalone executables orchestreert vanuit één binary. Draai je meer dan alleen containers, dan is die breedte een serieuze blik waard.

job "my-app" {
  datacenters = ["dc1"]

  group "web" {
    count = 3

    task "app" {
      driver = "docker"

      config {
        image = "my-app:latest"
        ports = ["http"]
      }

      resources {
        cpu    = 500
        memory = 256
      }
    }
  }
}

Voordelen:

  • Simpeler dan Kubernetes
  • Kan meer dan containers (raw exec, Java, QEMU)
  • Goede integratie met andere HashiCorp tools (Consul, Vault)
  • Single binary, makkelijk te deployen

Nadelen:

  • Kleiner ecosysteem
  • Minder managed cloud opties
  • Minder “standaard” (minder resources, tutorials)

Platform-as-a-Service

Wanneer: Je wilt gewoon code deployen, geen infrastructuur beheren.

  • Render: Simple deploys, managed PostgreSQL
  • Railway: Developer-friendly, goede free tier
  • Fly.io: Edge deployment, goede performance
  • Heroku: De originele, nog steeds solide
# Fly.io voorbeeld
fly launch
fly deploy

Geen YAML. Geen clusters. Geen ops. De ruil is wel echt, en dat verzwijg ik niet: je geeft controle uit handen aan het platform van iemand anders, wat lijnrecht ingaat tegen de soevereiniteit waar ik normaal voor pleit. Voor een side project of een vroeg product dat moet shippen kan dat een eerlijke deal zijn. Stap er alleen in met je ogen open over wie de uitknop bezit.

Voordelen:

  • Nul infrastructuur beheer
  • Push code, app draait
  • Vaak goedkoper voor kleine projecten

Nadelen:

  • Vendor lock-in
  • Minder controle
  • Kan duur worden bij schaal

Gewoon VMs

Wanneer: Je hebt geen containers nodig.

Ik meen het. Niet alles hoeft een container te zijn. Een saaie server met een service manager houdt dingen al decennia online, en je krijgt het zo inspecteerbaar als infrastructuur maar kan zijn.

Een Python app met systemd:

[Unit]
Description=My App
After=network.target

[Service]
User=app
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/venv/bin/python app.py
Restart=always

[Install]
WantedBy=multi-user.target

Ansible voor configuration management. Geen Docker, geen Kubernetes.

Voordelen:

  • Simpel
  • Geen container overhead
  • Bekend bij de meeste engineers
  • Debuggen is makkelijk

Nadelen:

  • Geen isolatie zoals containers
  • Dependency management lastiger
  • Minder reproduceerbaar

Serverless / FaaS

Wanneer: Event-driven workloads, variabele load, wil geen servers beheren.

  • AWS Lambda
  • Google Cloud Functions
  • Azure Functions
  • Cloudflare Workers
// AWS Lambda
export const handler = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify({ message: "Hello!" })
  };
};

Voordelen:

  • Pay per execution
  • Automatisch schalen naar nul
  • Geen server beheer

Nadelen:

  • Cold starts
  • Vendor lock-in
  • Lastig voor langlopende processen
  • Debugging is complex

Decision framework

Dus hoe kies je echt, in plaats van standaard te kiezen? Vijf vragen brengen me meestal een heel eind.

1. Hoeveel services heb ik?

  • 1-3 services: Docker Compose of PaaS
  • 4-10 services: Swarm, Nomad, of Kubernetes
  • 10+ services: Kubernetes wordt relevanter

2. Heb ik dynamisch schalen nodig?

  • Nee: Bijna alles behalve Kubernetes
  • Ja, maar voorspelbaar: Scheduled scaling, geen K8s nodig
  • Ja, onvoorspelbaar: Kubernetes of serverless

3. Wat is mijn team’s expertise?

  • Geen Kubernetes ervaring: Begin niet met Kubernetes
  • Enige ervaring: Managed Kubernetes (EKS, GKE)
  • Veel ervaring: Wat je wilt

4. Wat is mijn budget?

  • Klein (<$100/maand): VPS, PaaS, of serverless
  • Medium ($100-1000/maand): Afhankelijk van requirements
  • Groot (>$1000/maand): Kubernetes wordt economisch haalbaarder

5. Heb ik multi-cloud of hybrid nodig?

  • Nee: Gebruik wat de cloud biedt
  • Ja: Kubernetes is de beste optie voor portability

Wanneer Kubernetes wél de juiste keuze is

Ik heb deze hele post voor terughoudendheid gepleit, dus laat me net zo duidelijk zijn over de andere kant. Als de problemen echt zijn, is Kubernetes oprecht de beste tool die ik ken, en grijp ik er zonder aarzelen naar:

  • Veel microservices die onafhankelijk schalen
  • Team met Kubernetes expertise dat het kan onderhouden
  • Complexe deployment requirements (canary, blue-green)
  • Multi-tenant platform voor meerdere teams
  • Portability tussen clouds, precies waarom ik het in mijn eigen homelab draai. Dezelfde manifests verhuizen van een refurbished mini PC naar een cloud en terug, en die vrijheid is mij echte complexiteit waard.
  • Ecosysteem (Prometheus, ArgoCD en vrienden) dat je daadwerkelijk gaat gebruiken

Als een paar daarvan jou beschrijven, is Kubernetes waarschijnlijk de juiste keuze, en alles vóór deze sectie ging erover je hier bewust te laten aankomen.

Waarom we het toch kiezen

Hier is de eerlijke hindernis, het ding dat teams naar Kubernetes laat grijpen terwijl iets kleiners het ook zou doen. Kubernetes is het veilige antwoord in een vergadering. Niemand wordt afgerekend op het kiezen van de industriestandaard. Het staat goed op het architectuurdiagram en goed op een cv. Docker Compose kiezen voor een productie app voelt als toegeven dat je niet serieus bent, zelfs als het de slimmere engineeringkeuze is.

Volgens mij is dat omgedraaid. De zwaarste tool pakken om geloofwaardig te lijken is het tegenovergestelde van je eigen systeem begrijpen. De geloofwaardige zet is de tool bij het probleem laten passen en precies kunnen uitleggen waarom.

Mijn vuistregel

Start simpel. Voeg complexiteit toe wanneer je het nodig hebt, niet wanneer je denkt dat je het ooit nodig zou kunnen hebben.

Docker Compose voor development en kleine productie workloads. Kubernetes wanneer je de problemen hebt die Kubernetes oplost, en geen sprint eerder.

Hardop zeggen “we hebben Kubernetes niet nodig” is een teken van een team dat zijn eigen systeem begrijpt. Dat is de positie van waaruit je wilt argumenteren.

Afronding

Voordat je Kubernetes adopteert, zit even met drie vragen:

  • Welk probleem los ik op?
  • Is Kubernetes de simpelste oplossing voor dat probleem?
  • Heb ik de tijd, het geld en de expertise om het gezond te houden?

Een “nee” op een van die vragen is een zetje om naar de alternatieven te kijken. Docker Compose, Nomad, PaaS en gewone VMs bestaan allemaal omdat ze elk een vorm van probleem beter passen dan Kubernetes.

Je hoeft het hele bedrijf niet op het spel te zetten om dit te ontdekken. Draai de volgende interne tool op de simpelere stack. Meet setuptijd, buildtijd en hoe lang een nieuwe teamgenoot erover doet om zijn eerste wijziging te shippen. Laat de cijfers argumenteren. Mijn weddenschap is dezelfde die ik in mijn eigen infrastructuur maak: het beste systeem lost je probleem op met zo min mogelijk complexiteit, en blijft begrijpelijk wanneer je moe bent en het laat is. Soms is dat Kubernetes. Vaker dan de vacatures suggereren, is het dat niet.

Kies bewust.