16/06/2020
De vele varianten van DevOps
De term DevOps behoort inmiddels tot het standaard IT vakjargon. Een korte samenvatting van de termen en een stukje geschiedenis van de vele varianten van DevOps.
Blog
IT managers en DevOps engineers zullen in het begin niet veel nadenken over de grootte van hun Kubernetes (k8s) cluster. Meestal wordt er in een public cloud een Kubernetes dienst uitgerold en de eerste stappen gezet. Al gaandeweg leert men hoe Kubernetes werkt, maar daarbij trapt men in een aantal bekende valkuilen.
Naarmate er meer kennis aanwezig is en de wens ontstaat om het in productie te nemen moeten er een aantal vragen beantwoord worden, zodat je met een gerust hart die stap naar productie kan nemen. De vragen hebben betrekking op de grootte en het schalen van de clusters, maar ook op security. In dit artikel ga ik in op de grootte van de clusters.
Voor diegenen die bekend zijn met de opbouw van virtualisatie clusters zullen de overwegingen zeer herkenbaar zijn.
Als je microservices op Kubernetes wil hosten, wordt je geconfronteerd met enkele fundamentele vragen over het aantal Kubernetes-clusters en de grootte daarvan:
In dit artikel geef ik antwoord op of er zoiets is als een ideale cluster grootte. Ook beantwoord ik of alle apps in hetzelfde cluster moeten zitten of dat het beter is om juist meerdere clusters te hebben. In een volgend artikel zal ik de voor- en nadelen van grote en kleine worker nodes op een rij zetten.
Over het algemeen zijn er twee basisrichtingen die je kan hanteren: Eén of enkele grote clusters waarin een relatief groot aantal apps of enkele grotere apps draaien, of meerdere kleine clusters met slechts een paar apps of kleinere apps.
Beide opties zijn zeer goed mogelijk en verdedigbaar. Ik zet de voors van beide voor je op een rij.
Om een bepaalde set applicaties uit te voeren, heb je een bepaalde hoeveelheid compute nodig, zoals CPU-cores en geheugen.
Stel je voor dat je een capaciteit nodig hebt van 40 CPU-cores en 160 GB RAM. Dan zou je als volgt je totale cluster capaciteit beschikbaar kunnen maken.
De eerste optie levert de volledige benodigde capaciteit met één cluster. Alle apps draaien dus in hetzelfde cluster. Een dergelijk cluster bestaat uit veel relatief kleine of enkele grote worker nodes. De tweede optie behaalt de vereiste capaciteit met 5 clusters die elk 20% van de vereiste capaciteit leveren. Dit betekent dat elk cluster slechts een subset van de apps host. Dit type clusters bestaat uit slechts een paar kleine worker nodes.
Deze aanpak bestaat uit een beperkt aantal grote clusters die de benodigde capaciteit bieden. Het kan zelfs een heel groot cluster zijn waar alle apps op draaien, zoals in het voorbeeld hierboven. De voordelen van deze aanpak zijn de nadelen van een klein cluster.
Eén cluster is gemakkelijker te beheren dan veel clusters. Het updaten van Kubernetes kost minder tijd. Hetzelfde geldt voor updates voor andere cluster componenten, zoals de DNS-service of netwerk plug-ins.
Het configureren en onderhouden van monitoring, logging, tracing, service meshes, enzovoort heeft minder aandacht nodig. Hierdoor hebben al deze taken relatief weinig operationele overhead.
Aan de andere kant, als je veel clusters hebt, kan het een groot probleem zijn om al deze taken consistent uit te voeren en de verschillende clusters synchroon te houden. Je moet tijd en moeite steken in het ontwikkelen van tools en processen voor het efficiënt beheren of dit werk uitbesteden.
Meestal brengt een Kubernetes-cluster een aantal vaste kosten met zich mee die onafhankelijk zijn van de capaciteit van het cluster.
Met de Kubernetes-services van de meeste public clouds moet je voor elk cluster een vast bedrag betalen, ongeacht de grootte. Dat betekent dat als je één cluster hebt, je de vaste lasten van maar één cluster hebt. Als je 5 clusters hebt, betaal je dus 5 keer zoveel, zelfs als de totale capaciteit hetzelfde is.
Als je Kubernetes zelf beheert (on-premise of in de cloud), zijn de kosten waarschijnlijk hoger bij veel (kleine) clusters dan bij weinig (grote) clusters. Dit komt doordat je voor een hoge beschikbaarheid van elk cluster meerdere worker nodes moet hebben (meestal drie of vier). Als je dus 5 clusters hebt, is de hoeveelheid resources die je voor “failover” worker nodes moet reserveren 5 keer zo hoog als wanneer je maar één cluster hebt.
Kubernetes is ontworpen om de resources (CPU en geheugen) van het cluster optimaal te gebruiken. Dit wordt bereikt doordat de Kubernetes scheduler op basis van het resource profiel van een pod een optimale locatie kiest voor elke pod. Als je al je resources in één cluster bundelt, heb je een kleinere totale hoeveelheid verspilde resources als gevolg van overgebleven resources die niet meer kunnen worden gebruikt.
Als elk cluster bijvoorbeeld ongeveer 2 cores en 4GB RAM geheugen over heeft dat niet kan worden gebruikt voor workloads, en je hebt 10 clusters, verspil je in totaal 20 cores en 40 GB RAM. Aan de andere kant, als je maar één cluster hebt, is de overhead verwaarloosbaar.
Bovendien is er een vaste hoeveelheid resources nodig voor de beheer componenten van elk cluster, zoals de master nodes, etcd en de agents (kubelet). Als je kleine clusters hebt, is het deel van de resources dat je alleen voor het beheer nodig hebt veel hoger dan wanneer je grote clusters hebt.
Deze aanpak bestaat uit een groter aantal kleinere clusters die de benodigde capaciteit bieden. In de meest extreme gevallen kan er voor elke applicatie een apart cluster zijn. De voordelen van deze aanpak komen overeen met de nadelen van de vorige aanpak en vice versa.
De focus van Kubernetes ligt op het delen van infrastructuur en niet het bieden van isolatie tussen apps. Alle apps die in hetzelfde Kubernetes-cluster worden uitgevoerd, delen een bepaalde infrastructuur, zoals het netwerk en de DNS-service. Bovendien delen apps die op dezelfde worker node draaien de hardware (CPU en geheugen) evenals het besturingssysteem.
Dit kan een probleem zijn vanuit het oogpunt van beveiliging en compliance, vooral als Kubernetes wordt gebruikt als een systeem met meerdere tenants. Iemand kan bijvoorbeeld via een app misbruik maken van beveiligingsproblemen in de kernel van het besturingssysteem om toegang te krijgen tot de gegevens of andere minder prettige situaties creëren.
Een oplossing zou in dit geval kunnen zijn om voor elke klant of gevoelige microservices een apart cluster te hebben, zodat de apps van verschillende klanten zoveel mogelijk van elkaar worden geïsoleerd.
Apps die elk in een verschillend cluster worden uitgevoerd, zijn sterk van elkaar geïsoleerd. Er is geen gedeelde hardware, geen gedeeld netwerk en geen gedeelde besturingssystemen. Hierdoor wordt het risico op beveiligingsinbreuken tussen apps aanzienlijk verkleind.
Clusters kunnen worden georganiseerd met namespaces die de reikwijdte en zichtbaarheid van Kubernetes-resources beperken. Namespaces vormen ook de basis waarop toegangsrechten in het cluster worden georganiseerd.
Niet alle Kubernetes-resources hebben een namespace (zoals PersistentVolume, PodSecurityPolicy, PriorityClass, StorageClass en CustomResourceDefinition). Deze zijn niet aan een namespace gebonden, wat betekent dat ze zichtbaar zijn voor het hele cluster.
Met een groot cluster dat door veel apps en ontwikkelaars wordt gebruikt, zal je het gebruik van niet-namespace resources moeten coördineren om conflicten te voorkomen. Bovendien vereist het beheer van deze resources cluster brede rechten. Je wil niet alle ontwikkelaars deze toegang bieden.
Als je clusters klein en voor een specifiek doel ingezet worden dan hebben minder mensen toegang nodig tot elk cluster. Dit verkleint het risico op incidenten aanzienlijk, omdat de meeste fouten door mensen worden veroorzaakt. Het is een handige strategie om de productieversies van de apps op een apart cluster te hosten en de toegang tot dit productie cluster nog meer te limiteren. Idealiter is een productie cluster alleen toegankelijk voor een continuous delivery tool.
Wanneer je bijvoorbeeld maar één groot cluster hebt en daar vindt zich een groot incident plaats; downtime, security, enz, dan heeft het impact op al je apps in plaats van enkele apps of onderdelen van een app.
Als je over meerdere clusters beschikt en er eentje faalt, blijft de schade beperkt tot de apps die in dat cluster draaien. Het hebben van veel kleine clusters kan dus een strategie zijn om het risico op onverwachte incidenten te spreiden.
Als clusters erop gericht zijn om slechts een kleine set apps uit te voeren, kan je de hardware aanpassen aan de apps die ze hosten. Als een app bijvoorbeeld GPU’s vereist zoals een videobewerking applicatie, dan kan je cluster maken met worker nodes met een GPU.
Meerdere kleine of juist maar enkele grote clusters, wat is nou de juiste aanpak? Zoals altijd hangt het antwoord af van de casus en ligt de waarheid ergens in het midden.
De belangrijkste punten waar je rekening mee moet houden:
Je kan de twee strategieën prima mixen, zodat je jouw strategie nauw kan laten aansluiten op jouw business case.