Andere delen in de serie:
In de vorige publicatie eindigden we met de quote “Everything should be as simple as it can be, but not simpler.” We besloten immers aan het einde dat we de omgeving gingen opzetten met een automation tool als Ansible en dat we systemd gingen gebruiken voor de lifecycle van de Spring Boot applicatie. Waarom maakten we die keuze?
Het gebruik van Containers wordt een minder gemakkelijke keuze als het gaat om meer kritieke omgevingen. Uiteindelijk hangt het allemaal af van onze behoeften. Niet van die van andere mensen. De onze.
Een productie omgeving betekent verschillende dingen voor verschillende mensen. Beslissingen worden gemakkelijker als we weten wat het voor ons betekent. Welke garanties hebben we nodig? Welke risico’s zijn we bereid te nemen? Welke voordelen hebben we nodig, en welke afwegingen zijn we bereid te nemen?
Als we geen belangrijke gegevens te verliezen hebben is het ook niet zo belangwijk. Mocht er iets misgaan, dan creëren we eenvoudigweg de omgeving helemaal opnieuw. Natuurlijk is de gebruikte Spring Boot applicatie in de voorgaande publicatie uitermate geschikt om in een Container te draaien. Het bevat immers geen state. Maar wat als de applicatie nu wel state bevat, bijvoorbeeld in de vorm van een database?
In principe hoeft het geen probleem te zijn als we met een klein project bezig zijn, dan kunnen we beat een database in een Container draaien. We moeten er alleen voor zorgen dat we een volume koppelen om de gegevens persitent te maken en ervoor te zoregen dat er back-up processen aanwezig zijn (die natuurlijk getest worden om te controlleren of de back-ups goed zijn). In het geval van niet-cruciale gegevens zijn Containers handig en in het ergste geval herstellen we een back-up en kunnen weer verder.
Een anti-patroon is het gebruik van stateful applicaties met orkestratietools (die gebouwd zijn voor stateless applicaties). Voor stateless applicaties maakt het niet uit wanneer deze worden beëindigd (het wordt niet opgemerkt als een Container op een andere host wordt opgestart).
Dit is natuurlijk niet het geval voor databases (die hebben nu eenmaal de data nodig om goed te functioneren). Zo kunnen we bijvoorbeeld Kubernetes gebruiken met databases en gebruikmaken van zogenaamde ReplicaSet of ReplicationController en dan maar hopen. In dit geval moeten we gebruikmaken van StatefulSets en PersistentVolumeClaims. Wat betekent dat ons cluster in staat moet zijn om PersitentVolumes te maken, die vanaf alle nodes toegankelijk zijn.
Als u Kubernetes gebruikt en uw database wordt uitgevoerd in een ReplicaSet of ReplicationController, is dat een ernstig probleem. U zou gebruik moeten maken van StatefulSets en PersistentVolumeClaims. Dit betekent dat uw cluster een manier moet bieden om PersistentVolumes te maken, die vanaf alle knooppunten toegankelijk zijn. Maar zelfs dan kunnen we niet zomaar een stateful app in een StatefulSet plaatsen en alles is in kan en kruiken. Nee, waar het uiteindelijk op neerkomt is tuning, we moeten ervoor zorgen dat de aannames die vereist zijn ook daadwerkelijk gehaald worden.
Goed, maar hoe zit het nu met productie-omgevingen? Is het een goed idee om productie-databases in Containers te draaien? En hier komen we weer waar we mee begonnen en dat kunnen we ook gelijk aannemen als een vuistregel: Hoe kunnen we complexiteit reduceren? Deste minder onbekenden er in onze software-stack zitten, deste makelijker het voor om dingen te onderhouden en op incidenten te reageren.
Databases zijn cruciale services. Het kost moeite om een database goed te laten draaien, en nog meer moeite om dat betrouwbaar te doen. Als de data echt belangrijk is en ten aller tijde veilig moet zijn, moeten we geen onnodige risico’s nemen.
Er zijn alternatieven manieren om meer stabiliteit te krijgen en het minder moeite kost een database goed te laten draaien, bijvoorbeeld database-services van een cloudprovider, zoals Amazon, Microsoft, Oracle, DataStax enzovoorts. Maar in sommige gevallen is de data zo belangrijk en met name gevoelig dat deze data niet in een managed database in de cloud mag, in geval kunnen we de volgende vragen stellen:
- Is er een goed onderhouden intern Kubernetes-cluster?
- Zijn de services in een betrouwbare staat als deze op een Kubernetes-cluster landen?
- Zijn er belangrijke redenen om Kubernetes voor alles te gebruiken?
misschien wel, maar in alle andere gevallen kunnen we voor databases Containers beter links laten liggen, en in plaats daarvan voor de database-server een dedicated machine kiezen, zodat er zo min mogelijk operationele complexiteit is.