
Apr 15, 2025
We kunnen allemaal wel een situatie bedenken waarin een applicatie niet meer reageert door onvoldoende resources voor de belasting die je op dat moment ontvangt. Een oplossing zou zijn om handmatig resources toe te voegen wanneer zo'n situatie zich voordoet, maar daar heeft niemand tijd voor. Dit is waar autoscaling om de hoek komt kijken. In deze blog leggen we uit wat (auto)scaling is en vertellen we meer over de verschillende manieren waarop je het kunt gebruiken binnen Kubernetes.
Scaling kan worden onderverdeeld in twee categorieën, horizontaal en verticaal schalen. Horizontaal schalen verwijst naar het toevoegen van extra replica's of machines om de belasting tussen hen te verdelen.
Verticaal schalen werkt daarentegen door de reeds bestaande infrastructuur te vergroten, zoals het toevoegen van meer CPU of geheugen aan een server.
Dit handmatig doen is echter tijdrovend, vooral wanneer de verhoogde belasting slechts voor een korte periode aanhoudt. Met andere woorden, je bent altijd te laat. Hier komt autoscaling om de hoek kijken, door automatisch horizontaal of verticaal te schalen wanneer de huidige inkomende belasting daar om vraagt.
Autoscaling is een vorm van schalen waarbij de beslissing om de belasting te verhogen of te verlagen automatisch door software wordt genomen. Kortom, het voegt resources toe wanneer je applicatie druk is en verwijdert ze wanneer ze niet meer nodig zijn. Omdat deze belasting gedurende de dag voortdurend kan veranderen, kan handmatig schalen zeer onhandig en inefficiënt worden.
Zowel horizontale als verticale autoscaling zijn beschikbaar binnen Kubernetes. Horizontaal schalen wordt ondersteund op zowel node- als pod-niveau, terwijl verticaal schalen alleen op het laatste niveau wordt ondersteund. Hieronder duiken we in hoe Kubernetes beide technieken implementeert om ultieme schaalbaarheid te bereiken.
Zoals de naam al suggereert, kunnen we met de Horizontal Pod Autoscaler (HPA) horizontaal schalen door extra replica's van een bepaalde pod toe te voegen.
De HPA werkt met een API-resource en een controller, die je aan een Deployment of StatefulSet koppelt met behulp van selector labels. Vervolgens vergelijkt de HPA-controller periodiek (standaard elke 15 seconden) de HPA-configuratie met de metrics van de pod. De meest voor de hand liggende metrics zijn CPU- en geheugengebruik.
Als je bijvoorbeeld een maximaal gebruik van 75% geheugen in de HPA specificeert, zal de HPA-controller een pod toevoegen zodra het gemiddelde gebruik van alle pods binnen deze replicaSet 75% of meer bereikt. Een belangrijke factor hierbij is dat je de resource requests & limits voor de pod correct hebt geconfigureerd.
In het geval van ontbrekende metrics, neemt de HPA-controller 100% van de gewenste meetwaarde aan in het geval van een scale-down, en 0% in het geval van een scale-up. Pod metrics worden uitgesteld tot 300 seconden na het starten van de pod. Deze periode kan worden aangepast met de horizontal-pod-autoscaler-cpu-initialization-period vlag.
Naast CPU- en geheugengebruik ondersteunt Kubernetes versie 1.23 het voeden van de HPA met aangepaste metrics, zoals netwerkactiviteit of bijvoorbeeld de lengte van een externe wachtrij. Dit is echter een vrij primitieve implementatie en geen zo uitgebreide oplossing als KEDA.sh, dat meer nauwkeurige controle biedt over je schalingsvereisten.
Naast de HPA is er ook een VPA, ook bekend als de Vertical Pod Autoscaler. In plaats van het aantal replica's te verhogen, werkt het op basis van het verhogen van de geconfigureerde resources van de pod naar de aanbevolen waarde. Deze waarde wordt bepaald door de VPA recommender, afhankelijk van de modus waarin deze is ingesteld.
De VPA bestaat uit drie componenten:
De updateMode van de VPA beïnvloedt de functionaliteit en kan op twee manieren worden geconfigureerd:
Advies wordt gegenereerd op basis van live data en hangt daarom niet af van een vooraf bepaalde benchmark om de juiste resources te bepalen. Dankzij het resourceadvies van de VPA, verspil je minder resources en kun je mogelijk met minder nodes toe; wat resulteert in grote kostenbesparingen omdat clusternodes efficiënter worden gebruikt.
Beperkingen: De VPA is ongeschikt voor Java-gebaseerde applicaties, vanwege het beperkte inzicht in het daadwerkelijke geheugengebruik omdat Java het meeste beschikbare geheugen toewijst bij het uitvoeren, zelfs als het niet "actief" wordt gebruikt.
Binnen Kubernetes kun je ook verschillende soorten scaling onderscheiden. Namelijk, één die replica's van de betreffende applicatie toevoegt of verwijdert en een andere die het cluster zelf vergroot. De cluster autoscaler is verantwoordelijk voor het laatste, die herhaaldelijk controleert of het cluster voldoet aan een van de volgende voorwaarden:
De cluster autoscaler is gebaseerd op een controller, die zowel communiceert met de Kubernetes API als met de API van de onderliggende Cloud Provider om nodes aan te vragen (of te verwijderen) van het cluster wanneer dat nodig is.
De hierboven genoemde methoden (Cluster autoscaling, HPA & VPA) zijn allemaal voorbeelden van resource-gebaseerd reactief schalen, wat betekent dat je altijd een vertraging hebt tussen het ontvangen van extra belasting en het schalen van je infrastructuur. Maar wat als je belasting niet direct gerelateerd is aan CPU- of geheugenbelasting? Of pieken zo kort dat een dergelijke vertraging de noodzaak voor scaling volledig zou wegnemen? Scaling op events kan hier een oplossing bieden, ook bekend als event driven autoscaling.
Event Driven Autoscaling stelt je in staat om te reageren op bijna elke metric, de mogelijkheden zijn praktisch eindeloos. Voorbeelden kunnen wachtrijlengtes, databaseactiviteit of een telling van HTTP-responscodes zijn.
Door te schalen op basis van events, kun je onmiddellijk reageren op veranderingen in activiteit, zonder de latentie veroorzaakt door het meten van CPU- en/of geheugenactiviteit van een bepaald tijdsvenster.
Daarnaast maakt event driven auto scaling het mogelijk om naar nul te schalen, wat neerkomt op: geen belasting = geen pods. Hoewel dit niet geschikt is voor alle workloads, kan het bij juiste configuratie enorm helpen besparen op resources.
Een goed voorbeeld van event driven autoscaling is KEDA, dat als operator binnen je cluster wordt geïnstalleerd om een aantal CRD's te bieden voor het schalen op events. Bij het schalen op events heb je een bron nodig om metrics van te krijgen. Deze worden Scalers genoemd, en er zijn talloze opties, waaronder maar niet beperkt tot de hieronder genoemde:
De Scaler kan worden geconfigureerd wanneer te triggeren op basis van de specificatie. Neem bijvoorbeeld de AWS SQS queue scaler, in essentie heeft deze slechts twee argumenten nodig om goed te functioneren:
Natuurlijk zijn er meer nauwkeurige controlemogelijkheden beschikbaar om aan je behoeften te voldoen, maar zelfs een basisopstelling zou heel coole functies mogelijk kunnen maken zoals schalen naar nul en het verhogen van replica's wanneer de wachtrij vol zit met berichten.
Of je nu wilt schalen bij verhoogde CPU/geheugenbelasting of meer nauwkeurige autoscaling-opties nodig hebt, Kubernetes biedt het allemaal. Meestal volstaat een eenvoudige HPA, vooral wanneer resources goed zijn geconfigureerd met behulp van de VPA recommender. Maar wanneer je belasting wat onvoorspelbaarder is in termen van reguliere rekenkracht of gebaseerd kan zijn op het verwerken van jobs, kan een product als KEDA een enorm verschil maken voor je infrastructuur.