Ik schrijf veel over Kubernetes en ik draai het thuis elke dag. Ik vind het mooi spul.
Dus het verbaast je misschien dat ik een flink deel van m’n tijd besteed aan mensen ervan afpraten.
Het gaat steeds zo. Een klein team, één product, een roadmap vol features waar klanten op wachten, en iemand heeft besloten dat de eerste mijlpaal een Kubernetes-cluster is. Minimaal drie nodes, etcd, een CNI , een ingress controller, cert-manager, een monitoringstack. Weken werk voordat één klant iets ziet. Iedereen knikt mee, want zo hoort een serieuze setup er nu eenmaal uit te zien.
Die eerste mijlpaal kan ook anders. Je gaat in een middag live, je kunt elk onderdeel benoemen, en je slaapt gewoon.
Deze post is voor wie voor die keuze staat. Kies Kubernetes omdat je het nodig hebt, of sla het over omdat je het niet nodig hebt, en weet welke van de twee je gedaan hebt.
De Kubernetes-hype
Kubernetes heeft gewonnen. Het is hét standaardantwoord voor container orchestration, elke cloud verkoopt een managed variant en elke DevOps-vacature noemt het. Zodra iets de vanzelfsprekende keuze is, vraagt niemand meer of het ook de juiste is. Voor Kubernetes wordt niet meer gekozen. Het wordt aangenomen.
Ik snap de aantrekkingskracht. Voor m’n eigen homelab heb ik het heel bewust gekozen, en daar heb ik genoeg over geschreven. Maar “iedereen draait het” is de zwakste reden die er is om iets te draaien, en al helemaal voor infrastructuur die je moet begrijpen als ze stukgaat.
Kubernetes verdient z’n 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 hebt. Alle vijf? Dan is Kubernetes een cadeau. Geen enkele? Dan zijn het pure kosten, en je betaalt in het enige waar een klein team het minst van heeft, 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 grofweg tien keer zoveel tijd, geld en denkwerk om er te komen. De onderste past in je hoofd.
Je team is klein
Kubernetes vraagt je veel te begrijpen voordat je het veilig kunt draaien. De kern, en dan 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 uren niet om dat allemaal te leren én te onderhouden, bovenop het bouwen van het product. Er sneuvelt iets. Wat ik zie sneuvelen zijn eerst de weekenden, en kort daarna de uptime.
Je traffic is voorspelbaar
De pronkfunctie is autoscaling. Zit je traffic stabiel op 100 requests per seconde zonder vervelende pieken, dan lost autoscaling een probleem op dat je niet hebt. Overprovision een beetje, zet een reminder voor over een half jaar, en 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 VPS van $20. Het verschil betaal je voor een abstractie die je niet gebruikt.
Je hebt geen microservices
Kubernetes is gebouwd voor microservices, veel kleine, onafhankelijke services die elk op hun eigen ritme schalen en omvallen. Een monoliet heeft die behoeften niet. Die op Kubernetes draaien is een Ferrari kopen voor de wekelijkse boodschappen. Werkt, maar elke feature waarvoor je betaalt staat werkloos op de oprit.
De verborgen kosten van Kubernetes
De prijs op het kaartje is het makkelijke deel. De kosten die pijn doen staan nooit op een factuur.
Operationele overhead
Ook 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
Gestaag, terugkerend werk, en iemand in het team wordt er eigenaar van, gepland 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 dan hebben we het nog niet over de ecosysteemtools die elk cluster er vroeg of laat bij krijgt. 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 als 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. 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 waar je doorheen moet als je wilt weten waarom er niks gebeurde. Op een goede dag merk je dat niet. Op een slechte dag, bij het vierde kubectl-commando, wel.
Alternatieven voor Kubernetes
Dus als het Kubernetes niet wordt, wat dan? Geen van deze is speelgoed. Elk is een tool waar ik in de juiste situatie naar grijp, en meerdere ervan draaien op dit moment echt productieverkeer voor echte bedrijven.
Docker Compose
Eén server, meerdere containers, een 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. Updaten is docker compose pull && docker compose up -d. Het hele mentale model past in één bestand dat je van boven naar beneden leest.
Wat je krijgt is iets wat iedereen in het team snapt, geen cluster-overhead, en een setup die overal werkt waar Docker draait. Developers zijn er dol op. Wat je inlevert is automatisch schalen, high availability, want het is één node, en het grootste deel van wat het woord orchestration betekent.
Docker Swarm
Je hebt meerdere nodes nodig, en Kubernetes is te veel.
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
Het slikt dezelfde Compose-files, zit ingebouwd in Docker, is zo opgezet en spant meerdere nodes. Het ecosysteem is klein, de community nog kleiner sinds Docker vol op Kubernetes inzet, en de featurelijst is korter.
HashiCorp Nomad
Je wilt orchestration zonder de Kubernetes-complexiteit, of je draait meer dan alleen containers.
Nomad is een lichte orchestrator voor containers, VMs en losse executables, uit één binary. Draai je meer dan 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
}
}
}
}
Simpeler dan Kubernetes, en het schedulet meer dan containers (raw exec, Java, QEMU). Het past goed bij de rest van de HashiCorp-tools, Consul en Vault, en één binary is zo uitgerold. De prijs is een kleiner ecosysteem, minder managed cloud-opties en minder standaard, dus minder tutorials en minder mensen die jouw probleem al eens hebben opgelost.
Platform-as-a-Service
Je wilt code deployen en geen infrastructuur beheren.
Render doet simpele deploys met een managed PostgreSQL. Railway is developer-vriendelijk met een goede free tier. Fly.io deployt naar de edge en presteert goed. Heroku is het origineel, en nog steeds solide.
# Fly.io voorbeeld
fly launch
fly deploy
Geen YAML, geen cluster, geen ops. De ruil is echt, en die praat ik niet weg. Je geeft de controle uit handen aan het platform van een ander, en dat gaat lijnrecht in tegen de soevereiniteit waar ik normaal voor pleit. Voor een side project of een jong product dat moet shippen kan dat een eerlijke deal zijn. Lees de prijspagina en de voorwaarden voordat je erop bouwt, want het platform kan allebei veranderen en jij niet.
Wat je krijgt is nul infrastructuurbeheer, code pushen en het draait, en voor een klein project vaak een lagere rekening. Wat je inlevert is de uitgang, de controle, en een voorspelbare rekening zodra je groeit.
Gewoon VMs
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 inspecteerbaarder wordt infrastructuur niet.
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 het configuratiebeheer. Geen Docker, geen Kubernetes.
Simpel, geen container-overhead, bekend bij de meeste engineers, en makkelijk te debuggen. Wat je kwijt bent is de isolatie die containers je geven, dependency management wordt lastiger, en de machine is minder reproduceerbaar.
Serverless / FaaS
Event-driven workloads, wisselende load, en niemand die servers wil 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!" })
};
};
Je betaalt per uitvoering, het schaalt vanzelf naar nul, en er zijn geen servers om te beheren. De andere kant is cold starts, vendor lock-in, een slechte match voor langlopende processen, en debuggen dat lastiger is dan het zou moeten zijn.
Decision framework
Dus hoe kies je, in plaats van standaard te kiezen? Vijf vragen brengen me meestal een heel eind.
Hoeveel services
Eén tot drie, en Docker Compose of een PaaS volstaat. Vier tot tien, en Swarm, Nomad of Kubernetes passen alle drie. Boven de tien begint Kubernetes z’n plek te verdienen.
Of de load beweegt
Beweegt hij niet, dan bijna alles behalve Kubernetes. Beweegt hij op een rooster, dan dekt scheduled scaling het en heb je daar geen K8s voor nodig. Beweegt hij en kun je het niet voorspellen, dan Kubernetes of serverless.
Wat het team kan
Geen Kubernetes-ervaring? Begin er dan niet mee. Een beetje? Managed Kubernetes (EKS, GKE). Veel? Draai wat je wilt.
Wat het budget is
Onder de $100 per maand een VPS, een PaaS of serverless. Tussen $100 en $1000 hangt het van de eisen af. Boven de $1000 begint Kubernetes economisch te kloppen.
Of het tussen clouds moet kunnen verhuizen
Zo niet, gebruik wat de cloud je geeft. Zo wel, dan is Kubernetes de beste optie voor portability die ik ken.
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. Heb je die problemen, dan is Kubernetes de beste tool die ik ken, en grijp ik er zonder aarzelen naar.
Veel microservices die onafhankelijk schalen. Een team met Kubernetes-kennis dat het kan onderhouden. Deployment-eisen die verder gaan dan een rolling restart, canary en blue-green. Een multi-tenant platform voor meer dan één team. Portability tussen clouds, en dat is precies waarom ik het in m’n eigen homelab draai. Dezelfde manifests verhuizen van een refurbished mini-PC naar een cloud en terug, en die vrijheid is mij echte complexiteit waard. En een ecosysteem, Prometheus, ArgoCD en vrienden, dat je gaat gebruiken in plaats van alleen installeren.
Herken je je in een paar daarvan, dan 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
Dus waarom blijven teams naar Kubernetes grijpen als iets kleiners het ook doet? Omdat Kubernetes het veilige antwoord is 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, ook als het de slimmere engineeringkeuze is.
Volgens mij is dat de omgekeerde wereld. De zwaarste tool pakken om geloofwaardig over te komen is het tegenovergestelde van je eigen systeem begrijpen. Geloofwaardig is de tool bij het probleem laten passen en kunnen uitleggen waarom.
Mijn vuistregel
Begin simpel. Voeg complexiteit toe op de dag dat je het nodig hebt, en geen dag eerder.
Docker Compose voor development en kleine productieworkloads. Kubernetes als je de problemen hebt die Kubernetes oplost, en geen sprint eerder.
Een team dat hardop “wij hebben Kubernetes niet nodig” kan zeggen, en erbij kan zeggen waarom, begrijpt z’n eigen systeem. In zo’n team wil ik zitten.
Afronding
Voordat je Kubernetes binnenhaalt, drie vragen. Welk probleem los ik op? Is Kubernetes daar de simpelste oplossing voor? Heb ik de tijd, het geld en de kennis om het gezond te houden?
Een “nee” op een van die drie is een zetje richting de alternatieven. Docker Compose, Nomad, een PaaS en gewone VMs bestaan allemaal omdat ze elk een soort probleem beter passen dan Kubernetes.
Je hoeft niet in één keer voor het hele bedrijf te beslissen. Zet de volgende interne tool op een Compose-file en een VPS, en kijk hoe ver die komt voordat iemand het cluster mist.
Ik draai Kubernetes thuis omdat ik de problemen heb die het oplost, en omdat ik het mooi vind. De meeste teams die ik ervan afpraat hebben die problemen nog niet. Zodra ze die wél hebben, help ik ze het cluster bouwen.
