Ik schrijf veel over Kubernetes. Ik gebruik het dagelijks. Ik ben er fan van.

Maar Kubernetes is niet altijd het antwoord.

Sterker nog: voor veel teams en projecten is Kubernetes de verkeerde keuze. Te complex, te duur, te veel overhead voor wat ze proberen te bereiken.

Dit is de post die ik schrijf voor iedereen die overweegt Kubernetes te adopteren. Niet om je ervan te weerhouden, maar om je te helpen een bewuste keuze te maken.

De Kubernetes hype

Kubernetes heeft gewonnen. Het is de de-facto standaard voor container orchestration. Elke cloud provider biedt managed Kubernetes aan. Elke DevOps vacature vraagt om Kubernetes ervaring.

Maar “iedereen doet het” is geen goede reden om iets te doen.

Kubernetes lost specifieke problemen op:

  • 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

Als je deze problemen niet hebt, lost Kubernetes niets voor je op. Het voegt alleen complexiteit toe.

Wanneer Kubernetes overkill is

Je hebt één applicatie

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

Waarom zou je Kubernetes nodig hebben?

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

Versus:

Je applicatie → Docker Compose → 1 server

De eerste optie kost je 10x meer tijd, geld, en cognitieve load. Voor exact dezelfde functionaliteit.

Je team is klein

Kubernetes vereist kennis. Niet alleen van Kubernetes zelf, maar van:

  • 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 2-3 developers die ook ops doen? Die hebben geen tijd om dit allemaal te leren en te onderhouden.

Je traffic is voorspelbaar

Kubernetes’ killer feature is automatisch schalen. Maar als je traffic voorspelbaar is — consistent 100 requests per seconde, geen spikes — dan heb je dat niet nodig.

Overprovision een beetje en je bent klaar.

Je budget is beperkt

Managed Kubernetes (EKS, GKE, AKS) kost geld:

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

Voor een simpele applicatie kijk je al snel naar $300-500/maand. Dezelfde app op een $20 VPS? Werkt ook.

Je hebt geen microservices

Kubernetes is ontworpen voor microservices. Veel kleine, onafhankelijke services die schalen en falen onafhankelijk van elkaar.

Een monoliet in Kubernetes zetten is als een Ferrari kopen om boodschappen te doen. Technisch mogelijk, maar je benut de mogelijkheden niet.

De verborgen kosten van Kubernetes

Operationele overhead

Zelfs met managed Kubernetes:

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

Dit is werk. Continu werk. Iemand moet het doen.

Leercurve

Kubernetes concepten die je moet begrijpen:

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

En dan heb ik het nog niet over de ecosysteem tools: Prometheus, Grafana, ArgoCD, cert-manager, external-dns, …

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

Dit is de minimale config voor één applicatie. Vergelijk met 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:

docker logs my-app

In Kubernetes:

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 dan kom je erachter dat het een ImagePullBackOff is vanwege een typo in de image naam, of een resource limit issue, of een node die vol zit, of…

Alternatieven voor Kubernetes

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 bent klaar. Updates? docker compose pull && docker compose up -d.

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 Kubernetes’ vergeten broertje. Simpeler, minder features, maar vaak genoeg.

# 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 kan orchestreren.

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.

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.

Serieus. Niet alles hoeft een container te 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

Vraag jezelf af:

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

Om eerlijk te zijn: er zijn goede redenen om Kubernetes te kiezen.

  • Veel microservices die onafhankelijk schalen
  • Team met Kubernetes expertise die het kan onderhouden
  • Complexe deployment requirements (canary, blue-green)
  • Multi-tenant platform voor meerdere teams
  • Portability tussen clouds belangrijk
  • Ecosysteem (Prometheus, ArgoCD, etc.) heeft waarde voor jou

Als dit op jou van toepassing is, is Kubernetes waarschijnlijk een goede keuze.

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 — niet eerder.

En wees niet bang om te zeggen: “We hebben Kubernetes niet nodig.” Dat is geen falen. Dat is engineering wijsheid.

Conclusie

Kubernetes is een geweldige tool. Voor de juiste use cases.

Maar het is niet de enige tool. En voor veel projecten is het niet de beste tool.

Voordat je Kubernetes adopteert, vraag jezelf af:

  • Welk probleem los ik op?
  • Is Kubernetes de simpelste oplossing voor dit probleem?
  • Heb ik de resources (tijd, geld, expertise) om Kubernetes te onderhouden?

Als het antwoord “nee” is op een van deze vragen, kijk dan naar alternatieven. Docker Compose, Nomad, PaaS, VMs — ze bestaan allemaal om een reden.

De beste infrastructuur is de infrastructuur die je problemen oplost met zo min mogelijk complexiteit. Soms is dat Kubernetes. Vaak is het dat niet.

Choose wisely.