Skip to main content

Kubernetes: oefening 2

In de eerste oefening lag de focus op het werken met een aantal van de basis-features in kubernetes. Je zou daardoor al een behoorlijk goed zicht moeten hebben op de verschillende entiteiten die je kan aanmaken, zoals deployments, services, persistent storage.

Eén van de features die Kubernetes zo geliefd maakt, zijn de vele deploymentopties én mogelijkheden zoals rolling updates. Daarmee kan je updates geleidelijk over je infrastructuur verspreiden. In dit lab demonstreren we dit.We bouwen daarbij ook een heel eenvoudige CI stap: elke push met nieuwe code zal een nieuwe container genereren.

De bezoeker van onze eenvoudige site zal connecteren met een http(s) load balancer en via die weg op de website terecht komen.

Schematisch:

graph TD; A([user]) --> NLB[Load balancer /ingress]; NLB --> SVC[service]; SVC --> DEPLOYMENT[deployment]; DEPLOYMENT --> AR; REPO[source repository]-->|cloud build trigger|AR[artefact registry];

Om dit mogelijk te maken is eerst wat setup nodig, die we stap voor stap zullen doorlopen.

Een overzicht van de stappen:

Stap 1 deed je vermoedelijk al eerder in het lab rond terraform en moet je dus niet herhalen.

  • Stap1: Zorg dat de parking-app-container uit de serverless oefening beschikbaar is op je registry.
  • Stap2: maak een K8S deployment
  • Stap3: maak en expose de service via een ingress object
  • Stap4: test/demonstreer autoscaling door zelf load te veroorzaken. Dat kan je doen met een éénvoudig scriptje of met bvb Locust.
  • Stap5: test/demonstreer rolling updates

Stap 2: maak een deployment

Maak in je cluster een nieuwe deployment aan. Dat kan terug met kubectl, maar het is ook mogelijk om dit met de cloud console te doen. Je krijgt dan een wizard te zien die je door de mogelijkheden gidst én de resulterende yaml genereert.

deploy workload

Maak deze deployment in een nieuwe namespace helloghent.

Stap 3: maak en expose de service

Dit komt vermoedelijk niet onverwacht: na het aanmaken van de deployment, is het ook nodig om die extern bereikbaar te maken. Deze keer doen we dat wel via de regels van de kunst: via een ingress object.

Eerst moet dus wel nog een service voorzien worden:

---
apiVersion: "v1"
kind: "Service"
metadata:
name: "helloghent-main-service"
namespace: "helloghent"
labels:
app: "helloghent-main"
spec:
ports:
- protocol: "TCP"
port: 80
targetPort: 80
selector:
app: "helloghent-main"
type: "NodePort"

Bemerk dat we deze van het type "nodeport" maken. Deze zal dus bereikbaar zijn buiten de cluster. We willen ook specifiek een http(s) load balancer, waarvoor een ingress object nodig is.

Maak dus ook zo'n ingress object aan. (alweer, dit kan zowel grafisch als via kubectl) Daarmee zal een http load balancer aangemaakt worden in gcp. Dat kan een poosje duren. De load balancer zal dan steeds kijken welke services actief zijn om de load te verdelen.

De kans is groot dat dit in eerste instantie faalt, omdat de backend als 'not healthy' gerapporteerd wordt. Dat is uiteraard wel zo, maar de firewall blokkeert die health checks by default. Die zal je dus nog moeten openen. In de documentatie vind je hoe je dat kan doen.

Ga niet verder voordat je service extern bereikbaar is.

Stap 4: test autoscaling

de webapplicatie die we gebruikten heeft een endpoint /calculatepi die voor een vertraging van 1 seconde zorgt bij een request. Werk zelf een scenario uit waarmee je kunstmatig load gaat toevoegen (daar zijn tools voor zoals jmeter, ab) om autoscaling te testen.

Dit commando kan je ongetwijfeld helpen:

kubectl autoscale deployment shell --min=2 --max=10 --cpu-percent=10
horizontalpodautoscaler.autoscaling/shell autoscaled
tip

Maak uitgebreid notities van hoe je dit testte. Dit zal namelijk ook moeten gedemonstreerd worden op het evaluatiemoment.

Stap 5: rolling updates

Schaal de webservice naar 10 pods. Pas daarna de app aan en voer een rolling update uit.

tip

Kies voor een visuele wijziging (wijziging tekst of kleur in output), zodat je heel snel verschillende versies kan onderscheiden. In je browser kom je door te refreshen steeds weer (round-robin) op andere nodes. Door snel te refreshen zal je de wijzigingen dus ook live kunnen zien doorvoeren.

Alweer enkele commando's om je op weg te zetten:

kubectl set image deployment/xxxx xxxx
kubectl rollout status <xxx> -n xxxx

Stel dat er toch problemen bemerkt worden met de rollout, met welk commando kan je dan de vorige image terugzetten?

tip

Ook hier: maak uitgebreid notities van hoe je dit testte. Dit zal namelijk ook moeten gedemonstreerd worden op het evaluatiemoment.