De eerste keer dat je een stateful workload op een self-hosted cluster draait, loop je tegen een muur. Geen cloud provider storage class om op te leunen. Alleen je nodes, hun disks, en een Postgres pod die weigert te schedulen omdat niets hem een PersistentVolume kan geven. Dus je gaat lezen, en binnen een uur heb je het teruggebracht tot twee namen die steeds terugkomen: Longhorn en Rook-Ceph.
Ik heb beide in productie gedraaid. Dus laat me mijn bias meteen op tafel leggen: op kleine clusters kies ik standaard Longhorn, en waarom precies leg ik verderop uit. Houd dat in je achterhoofd terwijl je leest, want het kleurt hoe ik dingen weeg. Beide zijn CNCF projecten, beide geven je gerepliceerde block storage die overleeft als een node sterft, en beide zijn goede software. Ze zijn het alleen oneens over hoeveel complexiteit je zou moeten tekenen.
Waar je eigenlijk tussen kiest
Longhorn is gedistribueerde block storage die vanaf dag één voor Kubernetes is geschreven. Elk volume wordt over je nodes gerepliceerd met gewone Linux storage primitieven, en er zit geen apart storage systeem onder dat je moet leren.
Rook-Ceph is een Kubernetes operator om Ceph heen. Ceph is een gedistribueerd storage systeem dat jaren ouder is dan Kubernetes, op plekken als CERN petabytes draait, en zijn hele feature set meebrengt: block, object, filesystem, erasure coding, alles. Rook leert Kubernetes hoe het te besturen.
Dat verschil in afkomst is het hele verhaal. Longhorn is geboren in je cluster. Ceph is komen inwonen en bracht veel bagage mee. Die bagage is nuttig als je hem nodig hebt en een last als je hem niet nodig hebt.
De criteria waar ik echt om geef
Een feature checklist vertelt je hier niks nuttigs, want beide tools vinken de meeste vakjes af. Wat telt is hoe een keuze uitpakt in de praktijk. Ik weeg vier dingen: hoeveel operationeel oppervlak ik op me neem, hoe het zich gedraagt onder failure (dit is storage, dus dit is het hele spel), hoe het omgaat met de resources die ik heb, en hoe ver het schaalt voordat het breekt. Performance telt ook mee, maar voor de meeste homelab en kleine-productie workloads is het zelden het ding dat de doorslag geeft, dus dat behandel ik als secundair.
Longhorn: degene die in je cluster woont
flowchart TD
subgraph longhorn["Longhorn Architectuur"]
subgraph node1["Node 1"]
E1["Longhorn Engine"]
R1["Replica"]
end
subgraph node2["Node 2"]
E2["Longhorn Engine"]
R2["Replica"]
end
subgraph node3["Node 3"]
R3["Replica"]
end
end
PV["PersistentVolume"] --> E1
E1 --> R1
E1 --> R2
E1 --> R3
Hoe Longhorn werkt
Het model is klein genoeg om in je hoofd te houden, en dat is het grootste deel van de aantrekkingskracht. Elke PVC krijgt zijn eigen Longhorn engine die als pod draait. Die engine schrijft je data naar replica’s op de lokale disks van meerdere nodes, en hij schrijft synchroon, dus er wordt niks ge-acknowledged tot elke replica het heeft. De workload praat met zijn volume over iSCSI, beschikbaar gesteld door de engine.
- Engine per volume: elke PVC krijgt een dedicated Longhorn engine (draait als pod)
- Replica’s op nodes: data gerepliceerd naar lokale disks van meerdere nodes
- Synchrone replicatie: alle replica’s geschreven voor acknowledge
- iSCSI frontend: engine stelt het volume beschikbaar via iSCSI aan de workload
Als ik wil weten wat een volume doet, open ik de Longhorn UI en zie ik het: welke replica’s gezond zijn, waar ze leven, of er een rebuild loopt. Geen black box. Dat past bij hoe ik infrastructuur wil draaien, zoals ik schreef in Sovereign Infrastructure - ik moet snappen wat ik draai, en Longhorn laat me dat.
Longhorn installeren
helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn longhorn/longhorn \
--namespace longhorn-system \
--create-namespace
Basis configuratie:
# longhorn-values.yaml
defaultSettings:
defaultReplicaCount: 3
defaultDataPath: /var/lib/longhorn
storageMinimalAvailablePercentage: 15
defaultLonghornStaticStorageClass: longhorn
persistence:
defaultClass: true
defaultClassReplicaCount: 3
Waar het schittert
Helm install, en je hebt storage. Geen dedicated storage nodes, geen pool topologie die je eerst moet ontwerpen. De ingebouwde web UI laat je volume management, backup status en node health zien zonder dat je iets hoeft te bedraden. Backups gaan rechtstreeks naar S3-compatible storage met incrementele snapshots, wat op mijn setup betekent dat ik hem op mijn eigen MinIO richt en het vergeet. Niks hiervan draagt legacy bagage, want er zit geen ouder systeem onder dat wordt aangepast.
Waar het je bijt
De eerlijke kosten zijn echt. Longhorn is goed voor de workloads die de meesten van ons draaien, maar het is niet gebouwd voor extreme IOPS, want al het verkeer van elk volume gaat door zijn eigen engine pod en die pod is een plafond. Het werkt goed tot ongeveer 100 nodes en wordt lastig daarboven. En elke replica is een volledige kopie van je data, dus drie replica’s betekent drie keer de ruwe capaciteit. Er is geen erasure coding om dat te verzachten.
Rook-Ceph: de optie met de zware bagage
flowchart TD
subgraph rook["Rook-Ceph Architectuur"]
subgraph mgmt["Management"]
OP["Rook Operator"]
MON["Ceph Monitors"]
MGR["Ceph Manager"]
end
subgraph storage["Storage"]
OSD1["OSD<br/>(disk 1)"]
OSD2["OSD<br/>(disk 2)"]
OSD3["OSD<br/>(disk 3)"]
OSD4["OSD<br/>(disk 4)"]
end
subgraph access["Toegang"]
RBD["RBD<br/>(Block)"]
RGW["RGW<br/>(Object)"]
CFS["CephFS<br/>(Filesystem)"]
end
end
PV["PersistentVolume"] --> RBD
RBD --> OSD1
RBD --> OSD2
Hoe Rook-Ceph werkt
Ceph’s model is oprecht slim, en die slimheid is precies waarom er meer te leren valt. Elke disk wordt een OSD, een Object Storage Daemon. Data spreidt over die OSDs met het CRUSH algoritme en placement rules die jij definieert, zodat Ceph bepaalt waar elk stuk data leeft op basis van je failure domains in plaats van domme round-robin. Daarbovenop krijg je drie manieren naar binnen: block via RBD, S3-compatible object storage via RGW, en een echt filesystem via CephFS. Wat het geheel bij elkaar houdt is een quorum van monitor daemons die cluster state bijhouden.
- OSDs op disks: elke disk wordt een Object Storage Daemon
- CRUSH algoritme: data gedistribueerd over OSDs met placement rules
- Meerdere toegangsmethoden: block (RBD), object (S3-compatible), filesystem (CephFS)
- Monitors voor consensus: cluster state beheerd door monitor daemons
Elk van die bewegende delen is iets dat je kunt inspecteren, wat geweldig is, en iets dat je moet snappen als het zich misdraagt, en dat is de catch.
Rook-Ceph installeren
helm repo add rook-release https://charts.rook.io/release
helm repo update
# Installeer Rook operator
helm install rook-ceph rook-release/rook-ceph \
--namespace rook-ceph \
--create-namespace
# Maak Ceph cluster
kubectl apply -f ceph-cluster.yaml
Cluster configuratie:
# ceph-cluster.yaml
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
name: rook-ceph
namespace: rook-ceph
spec:
cephVersion:
image: quay.io/ceph/ceph:v18.2.0
mon:
count: 3
allowMultiplePerNode: false
mgr:
count: 2
storage:
useAllNodes: true
useAllDevices: false
deviceFilter: "^sd[b-z]" # Gebruik sdb, sdc, etc.
resources:
mon:
requests:
cpu: 500m
memory: 1Gi
osd:
requests:
cpu: 500m
memory: 2Gi
Waar het schittert
Hier betaalt de bagage zich terug. Ceph handelt petabytes, het soort schaal dat draait bij CERN en Bloomberg, dus je groeit er niet uit. Je krijgt block, object en filesystem storage uit één systeem, plus erasure coding, snapshots en cross-cluster mirroring. Het tuning oppervlak is enorm, wat betekent dat een team dat weet wat het doet het naar een specifieke workload kan vormen. En erasure coding snijdt in de storage overhead: in plaats van 3x te betalen voor replicatie kom je dichter bij 1.5x, en op grote capaciteit is dat echt geld bespaard.
Waar het je bijt
Dezelfde kracht is dezelfde kost. Er zijn veel meer bewegende delen, en monitors, managers en OSDs willen allemaal resources en aandacht. De vloer ligt hoog: drie monitors, twee managers en je OSDs voordat je één byte hebt opgeslagen, en de geheugen-footprint is significant. Ceph draagt decennia aan features en configuratie, dus de leercurve is steil en hij vlakt niet snel af. Voor echte performance eindig je vaak met nodes die je aan OSDs toewijdt, oftewel hardware die je specifiek voor storage opzij hebt gezet. Niks daarvan is een fout. Het is de prijs van wat Ceph je geeft, en je wilt hem alleen betalen als je gebruikt wat je gekocht hebt.
Naast elkaar
| Aspect | Longhorn | Rook-Ceph |
|---|---|---|
| Complexiteit | Laag | Hoog |
| Setup tijd | 10 minuten | 30+ minuten |
| Resource overhead | Laag | Hoog |
| Max schaal | ~100 nodes | 1000+ nodes |
| Storage types | Alleen block | Block, Object, Filesystem |
| Performance | Goed | Excellent (na tuning) |
| Storage efficiëntie | 3x (replicatie) | 1.5x+ (erasure coding) |
| Backup | Ingebouwd S3 | Externe tools |
| UI | Excellent | Ceph Dashboard |
| Community | Groeiend | Mature |
De tabel is handig voor een snelle blik, maar de beslissing zit in de rijen die je echt voelt. Voor mij zijn dat de resource overhead en de complexiteit kolommen, want dat zijn de dingen waar ik elke dag dat een cluster draait voor betaal, niet alleen op de dag dat ik het installeer.
Wanneer Longhorn de juiste keuze is
Pak Longhorn als de vorm van je situatie er zo uitziet:
- Kleine tot medium clusters (onder 100 nodes)
- Simpelheid belangrijk is en je storage wilt die gewoon werkt
- Beperkte ops capaciteit, een klein team dat geen tijd kan steken in het babysitten van storage
- Algemene workloads zoals databases en stateful apps met moderate I/O
- Homelab of edge waar resources krap zijn
# Typische Longhorn workload
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 100Gi
Wanneer Rook-Ceph zijn kost verdient
Pak Rook-Ceph wanneer:
- Grote clusters (100+ nodes)
- Meerdere storage types nodig, block EN object EN filesystem uit één systeem
- Performance kritiek en je voor specifieke workloads moet tunen
- Storage efficiëntie belangrijk en erasure coding je echt capaciteit bespaart
- Dedicated storage team, mensen die Ceph kunnen leren en goed opereren
Dat laatste punt slaan mensen over. Ceph beloont een team dat het kent en straft een team dat het niet kent. Als niemand de storage bezit, bezit de complexiteit jou.
# Rook-Ceph met erasure coding
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: replicated-pool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3
---
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: erasure-coded-pool
namespace: rook-ceph
spec:
failureDomain: host
erasureCoded:
dataChunks: 2
codingChunks: 1
De nuance rond performance
Dit is het criterium dat ik eerder parkeerde, en hier is waarom het zelden de doorslag geeft. Voor de workloads die de meeste mensen draaien zijn beide snel genoeg, en het verschil komt pas aan de randen tevoorschijn.
Longhorn onder belasting
# Tune replica count voor performance vs durability
defaultSettings:
defaultReplicaCount: 2 # Sneller dan 3, minder durable
# Gebruik dedicated disk pad
defaultDataPath: /mnt/fast-ssd/longhorn
Longhorn is I/O bound door die per-volume engine pod. Duw een high-IOPS workload erdoorheen en de engine wordt je bottleneck, en dat is de trade-off die je accepteert voor de simpele architectuur.
Rook-Ceph onder belasting
# Dedicated OSD nodes
spec:
placement:
osd:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: storage-node
operator: In
values:
- "true"
# NVMe optimalisatie
storage:
config:
osdsPerDevice: "1"
storeType: bluestore
Ceph kan moderne NVMe drives satureren als het correct geconfigureerd is. De zin “als het correct geconfigureerd is” draagt daar gewicht, en dat punt bereiken is precies het werk waar je voor tekent.
Backups
Storage waar je niet van kunt restoren is geen storage, het is een liability met een aftelklok. Dus dit telt zwaarder dan ruwe throughput.
Longhorn backups
Ingebouwd. Configureer een S3 target:
defaultSettings:
backupTarget: s3://longhorn-backups@us-east-1/
backupTargetCredentialSecret: longhorn-s3-credentials
Schedule backups per volume:
apiVersion: longhorn.io/v1beta1
kind: RecurringJob
metadata:
name: daily-backup
spec:
cron: "0 2 * * *"
task: backup
groups:
- default
retain: 7
Rook-Ceph backups
Er is geen equivalente ingebouwde flow, dus je grijpt naar Velero met Ceph CSI snapshots:
velero install \
--provider aws \
--plugins velero/velero-plugin-for-csi \
--features=EnableCSI
Of native Ceph mirroring voor disaster recovery tussen clusters, wat oprecht fijn is zodra je op de schaal opereert waar een tweede cluster bestaat.
Mijn keuze, en wat ik echt draai
Tijd om de bias te verzilveren die ik bovenaan markeerde. Ik draai Longhorn in mijn homelab:
# Mijn Longhorn configuratie
defaultSettings:
defaultReplicaCount: 2 # 3 nodes, 2 replica's
defaultDataPath: /mnt/storage/longhorn
backupTarget: s3://backups@minio/longhorn/
backupTargetCredentialSecret: minio-credentials
storageMinimalAvailablePercentage: 20
persistence:
defaultClass: true
Drie nodes is het beslissende feit. Dat is te klein om Ceph’s overhead te rechtvaardigen, waar de monitors en managers alleen al een stuk capaciteit zouden opeten dat ik niet kan missen. De 2-uur-’s-nachts test beslist de rest: als een volume zich misdraagt en ik half wakker ben, wil ik de Longhorn UI openen en zien wat er mis is, niet door Ceph internals bladeren in een poging te onthouden welke daemon wat doet. Backups landen in mijn eigen MinIO over S3, en elke vrije MB blijft vrij op kleine nodes.
De dag dat ik 50-plus nodes draai of echt object storage naast block nodig heb, switch ik naar Ceph en betaal ik graag de complexiteits-tax, want op dat punt zou ik gebruiken waar ik voor betaald heb. Die dag is er nog niet. Jouw context kan hem een stuk dichterbij leggen, en als je het team en de schaal hebt, is Ceph een fantastische keuze. Lees je eigen situatie, niet de mijne.
Later migreren als je Longhorn ontgroeit
Begin je op Longhorn en ben je bang dat je jezelf vastschildert in een hoek? Dat doe je niet. De weg eruit is saai, wat het beste is wat je over een migratie kunt zeggen:
- Backup de data van het Longhorn volume
- Deploy Rook-Ceph ernaast
- Restore naar Ceph volumes
- Update workloads om de nieuwe StorageClass te gebruiken
- Retire Longhorn zodra alles verplaatst is
Beide spreken CSI, dus je workloads zien hoe dan ook dezelfde interface. De switch is een StorageClass wijziging, geen herschrijving.
Kies de complexiteit die je kunt dragen
Storage is het deel van Kubernetes dat fouten het hardst afstraft. Doe het verkeerd en je verliest data, de ene failure mode die je niet kunt terugdraaien. Over-bouw het en je besteedt je weken aan het voeden van complexiteit die je nooit nodig had.
Map het op schaal en het antwoord rolt er meestal vanzelf uit. Homelab en kleine clusters wijzen naar Longhorn. Medium productie kan beide kanten op, afhankelijk van of die extra Ceph features hun kost verdienen. Grote schaal wijst naar Ceph. Beide zijn solide software, en beide zullen je goed dienen. Wat ze echt scheidt is hoeveel operationeel gewicht je wilt dragen, en dat is een vraag die alleen jij voor je eigen cluster kunt beantwoorden.
Kies het simpelste ding dat je failure modes overleeft. Als het cluster eroverheen groeit, merk je het, en de deur naar buiten staat open.
