Omgaan met stateful services in containers
Kort antwoord
Gebruik StatefulSets met persistent volumes voor databases en andere stateful workloads die echt in containers moeten draaien, of houd die services op een VM of dedicated server als dat simpeler is. Test in beide gevallen regelmatig je backup- en restoreprocedure, want dat is het onderdeel dat er in de praktijk bij inschiet.
Waarom state het lastige deel is
Containers zijn ontworpen om stateless te zijn: een container kan altijd en overal worden gestopt en opnieuw ingepland, en dat is een feature, geen bug. Het is wat auto-scaling en self-healing mogelijk maakt. State doorbreekt die aanname. Een databasecontainer die naar een andere node wordt verplaatst, heeft zijn data nodig op de nieuwe plek, of een manier om weer verbinding te maken met storage die op zijn plek bleef, en dat moet gebeuren zonder dat er iets corrupt raakt tijdens het schrijven.
Dit is niet iets specifieks voor Worldstream: het is dezelfde afweging die iedereen die containers draait moet maken, op welke infrastructuur dan ook. De twee gangbare patronen om hiermee om te gaan komen hieronder aan bod.
Patroon één: StatefulSets met persistent volumes
Kubernetes heeft hier een speciaal object voor: de StatefulSet. In tegenstelling tot een gewone Deployment geeft een StatefulSet elke pod een stabiele, unieke netwerkidentiteit en een vaste verwijzing naar zijn eigen persistent storage. Als een pod opnieuw wordt ingepland, komt hij terug met dezelfde identiteit en koppelt hij weer aan hetzelfde volume in plaats van vanaf nul te beginnen.
De storage-kant hiervan wordt geregeld via PersistentVolumes en PersistentVolumeClaims: een PersistentVolumeClaim vraagt storage aan, en een PersistentVolume (gebaseerd op welke storage class je cluster ook heeft geconfigureerd) vervult die aanvraag en blijft gekoppeld aan die specifieke pod-identiteit bij elke reschedule. Dit is de standaard, beproefde manier om iets als een kleine database of een message queue in Kubernetes te draaien, als je eenmaal hebt besloten dat het daar moet staan.
Toch blijft dit operationeel bewerkelijker dan een stateless Deployment. Dingen als het vergroten van een volume, een ordentelijke failover uitvoeren, of een specifieke replica herstellen na een crash vragen bij een StatefulSet meer zorg dan bij stateless pods. Het is verstandig om daar vooraf rekening mee te houden, in plaats van het pas tijdens een incident te ontdekken.
Patroon twee: zet het helemaal niet in een container
Het andere legitieme antwoord is om het stateful deel niet te containeriseren. Niet helemaal: containers optimaliseren packaging en deployment, VM's bieden standaard sterkere isolatie en meer flexibiliteit op OS-niveau. Veel teams combineren beide: VM's voor de grenzen die er echt toe doen, containers voor de onderdelen die baat hebben bij snelheid en herhaalbare deploys.
Voor veel teams betekent dit dat de stateless applicatielaag in containers draait (op Kubernetes of anderszins), terwijl de database op een VPS of dedicated server staat, beheerd zoals databases altijd al werden beheerd: met goede backups, monitoring en iemand die de specifieke faalscenario's kent. Dat is geen compromis, het is vaak juist de simpelere en betrouwbaardere keuze, zeker als je team niet dagelijks ervaring heeft met het draaien van stateful workloads op Kubernetes. Zie Vervangen containers VM's? Het juiste isolatiemodel kiezen voor die afweging in meer detail.
Welk patroon je ook kiest, plan voor het faalscenario
Dat containers de hostkernel delen is ook een security- en compliance-overweging die het waard is om mee te nemen bij stateful, vaak gevoelige workloads: hardening (rootless draaien, seccomp en AppArmor/SELinux-profielen gebruiken), image scanning en signing, en, waar de compliance-eis daarom vraagt, de container binnen een VM draaien voor sterkere isolatie.
Welk patroon je ook kiest: wat uiteindelijk bepaalt of een stateful service een slechte dag overleeft, is of backup en restore daadwerkelijk zijn getest, niet alleen geconfigureerd. Een backup waar je nog nooit vanaf hebt hersteld, is een hoop, geen plan. Zie voor de storage-kant hiervan de Storage-categorie voor richtlijnen over Block Storage en Backup Storage.