← keuze

Cloud infrastructure

Kubernetes

Software container management

Je webshop draait in 40 containers, verspreid over 6 servers.
Om 3 uur 's nachts valt server 4 uit.

Wie start die containers opnieuw op? Op welke server? En hoe vinden de andere containers ze daarna terug?

Leerdoelen

Na deze les kan je:

  • uitleggen waarom containerorchestratie nodig is
  • Docker Compose en Kubernetes vergelijken
  • de architectuur van een Kubernetes cluster beschrijven: control plane en nodes
  • de belangrijkste bouwblokken herkennen en in YAML gebruiken: pod, deployment, service, gateway, namespace, secret, persistent volume claim
  • een applicatie deployen, bevragen, schalen en updaten met kubectl
  • inschatten wanneer Kubernetes (niet) de juiste keuze is

Inhoud

  1. Even herhalen: software containers
  2. Low tech oplossing: Docker Compose
  3. High tech oplossing: Kubernetes
    • situering
    • architectuur
  4. Bouwblokken
  5. Werking: kubectl, schalen, netwerken, storage, demo
  6. Verder: Helm, operators, GitOps…
Getekende haven met containers, kranen en schepen als metafoor voor DevOps en Kubernetes

Deel 1

Even herhalen: software containers

Virtuele machines vs. containers

Virtuele machines App 1 App 2 App 3 bins / libs bins / libs bins / libs Guest OS Guest OS Guest OS Hypervisor Host OS Infrastructuur Containers App 1 App 2 App 3 bins / libs bins / libs bins / libs Container runtime (containerd, Docker…) Host OS: gedeelde kernel Infrastructuur geen guest OS: start in (milli)seconden, image van enkele MB's

Software containers

  • Gebruiken de kernel van de host
    • moeten daarom niet opstarten zoals een OS
    • kunnen daardoor erg klein gemaakt worden
  • Worden opgebouwd met een Dockerfile (of Containerfile) tot een image, volgens de open OCI-standaard
  • Bieden isolatie ten opzichte van andere containers, gebaseerd op namespaces (wat zie je?) en cgroups (hoeveel mag je gebruiken?) in Linux
  • Een image draait overal hetzelfde: laptop, CI-pipeline, Cloud Run, Kubernetes…
Meer weten: Understanding the Docker internals

Waar staan containers?

Evolutie van physical, virtual en containers naar serverless, met deployment speed, high availability, schaalbaarheid en kosten per stap

Dockerfile

Een Dockerfile beschrijft stap voor stap hoe een image gebouwd wordt.


FROM ubuntu:24.04
LABEL maintainer="roel.vansteenberghe@odisee.be"
RUN apt-get update \
 && apt-get install -y nginx \
 && rm -rf /var/lib/apt/lists/*
COPY index.html /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
								
  • FROM: de image waarop je verder bouwt
  • Elke RUN, COPY en ADD maakt een nieuwe laag. Lagen worden gecachet en gedeeld tussen images.
  • COPY: bestanden in de image plaatsen
  • CMD / ENTRYPOINT: het ene proces dat de container start
  • EXPOSE documenteert de poort. Publiceren gebeurt pas bij het starten (docker run -p 8080:80).

Uitdagingen voor containerbeheer

Horizontaal schalen

  • Hoe verdeel je containers over je hosts?
  • Hoe ga je ze load balancen?
  • Kan dat automatisch, in functie van de load?

Netwerken

  • Hoe blijft een container bereikbaar als hij van host verandert?
  • Hoe communiceren de lagen van een multi-tier applicatie over meerdere hosts?

Storage

  • Wat met containers die data bewaren? (databank, uploads van een website…)
  • Wat als die container naar een andere host verhuist?

En ook: self-healing, updates zonder downtime, secrets, ...

Deel 2

Low tech oplossing: Docker Compose

Docker Compose

  • Beschrijft een applicatie van meerdere containers in één YAML-bestand (compose.yaml)
  • Containers vinden elkaar via hun servicenaam (bv. webserver → databank)
  • Eenvoudig op te zetten: één commando
  • Maar: beperkt tot één host, geen self-healing over hosts heen, geen autoscaling
  • Sinds Compose v2 een plugin van de Docker CLI: docker compose (de oude Python-versie docker-compose wordt niet meer ondersteund)

Ideaal voor development, tests en kleine setups

Docker Compose logo

compose.yaml: Wordpress + databank


services:
  database:
    image: mariadb:11.4
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MARIADB_ROOT_PASSWORD: somewordpress
      MARIADB_DATABASE: wordpress
      MARIADB_USER: wordpress
      MARIADB_PASSWORD: wordpress
								

  wordpress:
    image: wordpress:latest
    volumes:
      - wp_data:/var/www/html
    ports:
      - "80:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: database
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress

volumes:
  db_data:
  wp_data:
								
Bron: awesome-compose – Wordpress sample

Wat valt op?

  • Elke container krijgt een servicenaam. Die gebruik je om ernaar te verwijzen, bv. WORDPRESS_DB_HOST: database. Je hoeft dus geen ip-adressen te kennen.
  • Dat werkt via de ingebouwde DNS-server van Docker, op het netwerk dat Compose voor deze applicatie aanmaakt.
  • ports: hoe de container van buitenaf bereikbaar is. Dit is de -p-parameter van docker run. De databank heeft geen ports: die is enkel intern bereikbaar.
  • volumes: data die het herstarten (en verwijderen) van een container overleeft.
  • restart: always: crasht een container, dan start Docker hem opnieuw. Maar enkel op deze host.

Opstarten


docker compose up -d      # opstarten op de achtergrond (= daemon)
docker compose ps         # welke containers draaien er?
docker compose logs -f    # logs volgen
docker compose down       # alles stoppen en opruimen (volumes blijven)
						

En als je 3 servers hebt in plaats van 1? En als er één uitvalt?

Deel 3

High tech oplossing: Kubernetes

Kubernetes

  • Komt uit de stal van Google (geïnspireerd op het interne systeem Borg), sinds 2015 open source en geschonken aan de CNCF
  • Een erg actief project: 3 releases per jaar, elke release krijgt ongeveer 14 maanden ondersteuning
  • Kan lokaal geïnstalleerd worden, maar wordt meestal gebruikt als managed dienst: GKE (Google), EKS (AWS), AKS (Azure)
  • Een erg universeel framework met plugins voor container runtime (CRI), netwerk (CNI) en storage (CSI)
  • Je beschrijft wat je wil (declaratief), Kubernetes zorgt voor het hoe
Releases: kubernetes.io/releases

Situering

  • Door de adoptie bij Google, AWS en Azure de de facto standaard voor containerbeheer
  • Gericht op specialisten: terminal first (kubectl voor Windows, Linux en Mac), beperkte GUI
  • Verschillende distributies die een meerwaarde willen bieden tegenover 'vanilla' Kubernetes: OpenShift (Red Hat), Rancher (SUSE), Tanzu (Broadcom), k3s…
  • Snelle ontwikkeling: features gaan van alpha naar beta naar GA, en geregeld wordt iets deprecated
    • bv. Docker als runtime (dockershim) verdween in v1.24
    • bv. Ingress wordt niet meer verder ontwikkeld, de Gateway API is de opvolger
  • Worker nodes kunnen ook Windows-machines zijn

Een ecosysteem van aanbieders

Honderden logo's van Kubernetes certified service providers
Nog uitgebreider: landscape.cncf.io

Eén schakel in de DevOps-keten

DevOps-cyclus plan, build, integration, deploy, operate met logo's van tools, waaronder Kubernetes en Docker
Meme: I love it when a plan comes together

Architectuur van een cluster

Clients kubectl console / UI CI/CD Control plane API server Scheduler Controllermanager etcdcluster state Cloud controllerLB's, disks… bij GKE, EKS en AKS beheerd door de provider Node 1 kubelet kube-proxy containerd pod pod pod Node 2 kubelet kube-proxy containerd pod pod Node n kubelet kube-proxy containerd pod Image registry pull image

Wie doet wat?

Control plane

  • API server: de enige toegangspoort, alles is een REST-call
  • etcd: key-value store met de volledige toestand van de cluster
  • Scheduler: kiest op welke node een nieuwe pod komt (resources, labels, affiniteit)
  • Controller manager: stuurt continu bij tot de cluster overeenkomt met de gewenste toestand
  • Cloud controller manager: maakt load balancers, disks… bij de cloudprovider

Node

  • kubelet: agent die de pods op de node start en bewaakt, en rapporteert aan de API server
  • Container runtime: voert de containers uit (containerd, CRI-O)
  • kube-proxy: zorgt dat het verkeer naar een service bij de juiste pods komt. Soms vervangen door eBPF (Cilium, bij GKE: Dataplane V2).
Bron: kubernetes.io – Kubernetes components

De kern: desired state

1. Gewenst replicas: 3 (YAML, bewaard in etcd) 2. Observeer er draaien 2 pods (node viel uit) 3. Vergelijk 1 pod te weinig 4. Actie start 1 nieuwe pod op een gezonde node en dat eindeloos opnieuw

Jij beschrijft de gewenste toestand, controllers zorgen er continu voor dat de werkelijkheid volgt: self-healing.

Deel 4

Bouwblokken

De belangrijkste objecten

ObjectWat?
Node(virtuele) machine die deel uitmaakt van de cluster en pods uitvoert
Podkleinste eenheid: één of meer containers met gedeeld netwerk en volumes, met een intern ip-adres
Deploymentgewenste toestand van een applicatie: welke image, hoeveel pods, hoe updaten
Servicestabiel adres (en load balancing) voor een groep pods
Ingress / Gatewayinkomend http(s)-verkeer van buiten de cluster naar services routeren. Gateway is de opvolger van Ingress.
Namespacelogische scheiding binnen de cluster (project, klant, omgeving)
Secret / ConfigMapconfiguratie en gevoelige gegevens, los van de image
PersistentVolumeClaimaanvraag voor persistente opslag

Configuratie via kubectl, YAML (of JSON) en deels via de GUI van je cloudprovider

Bouwblok: node

  • Een node is simpelweg een machine, meestal een VM, waarop pods geplaatst kunnen worden
  • Het besturingssysteem varieert, maar vaak is het een gespecialiseerd OS met een kleine footprint (bv. Container-Optimized OS bij GKE, Bottlerocket bij AWS, Talos)
  • Nodes met dezelfde configuratie vormen een node pool, die je kan laten autoscalen
  • Opgelet: niet alle resources zijn bruikbaar voor jouw pods. Het OS, de kubelet en systeempods nemen per node al snel 1 GB of meer. Kijk naar Allocatable in kubectl describe node.

Bouwblok: pod

Vier pods met elk een eigen ip-adres, met één of meer containers en volumes
  • Bevat één of meer containers en volumes. De containers delen het netwerk (localhost) en de volumes.
  • Elke pod krijgt één intern ip-adres: bereikbaar vanuit andere pods, niet van buiten de cluster
  • Maak je in principe niet zelf aan: een deployment doet dat voor jou. Pods zijn wegwerpbaar.
Bron afbeelding: kubernetes.io – Kubernetes basics

Bouwblok: deployment

Kubernetes cluster met nodes, een containerized app en een deployment op de control plane
  • Bevat de desired state van een applicatie: image, aantal replica's, resources, update-strategie…
  • De control plane controleert continu of de applicatie nog voldoet (bv. aantal instanties) en stuurt bij waar nodig
  • Onder de motorkap maakt een deployment een ReplicaSet per versie. Zo kan je ook terug naar een vorige versie (rollback).

Deployment: YAML


apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.29
        ports:
        - containerPort: 80
								
  • apiVersion + kind: welk type object. Workloads zitten in apps/v1.
  • replicas: hoeveel pods er moeten draaien
  • selector: welke pods horen bij deze deployment? Moet overeenkomen met de labels in de template.
  • template: de blauwdruk van elke pod
  • Gebruik een concrete tag in plaats van latest: dan weet je wat er draait, en werken updates en rollbacks voorspelbaar

Requests en limits


containers:
- name: nginx
  image: nginx:1.29
  resources:
    requests:
      memory: "64Mi"  # 64 MiB RAM
      cpu: "100m"     # 0,1 core
    limits:
      memory: "128Mi"
      cpu: "500m"
								
  • Requests: wat de container minstens nodig heeft. De scheduler gebruikt dit om een node te kiezen.
  • Limits: het maximum. Te veel CPU = afgeremd, te veel geheugen = OOMKilled.
  • Een autoscaler op basis van CPU rekent in % van de request: zonder requests geen autoscaling.

Voeg altijd requests (en limits) toe

Health checks: probes

ProbeVraagAls ze faalt…
readinessProbeMag deze pod verkeer krijgen?pod tijdelijk uit de load balancing
livenessProbeLeeft de container nog?container wordt herstart
startupProbeIs de container al opgestart?de andere probes wachten tot die slaagt

readinessProbe:
  httpGet:
    path: /healthz
    port: 80
  periodSeconds: 5
						

Meer soorten workloads

ObjectGebruikVoorbeeld
Deploymentstateless, pods zijn inwisselbaarwebapp, API
StatefulSetpods met een vaste identiteit en eigen opslagdatabank, Kafka
DaemonSetprecies één pod op elke nodelog- of monitoring-agent
Jobloopt tot het werk klaar isdatamigratie
CronJobeen Job op vaste tijdstippennachtelijke backup

StatefulSets

Variant op een deployment, met sticky identity:

Unlike a Deployment, a StatefulSet maintains a sticky identity for each of its Pods. These pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling.
  • Vaste namen: mysql-0, mysql-1… met een vaste DNS-naam
  • Elke pod krijgt een eigen volume (volumeClaimTemplates), dat hem volgt bij een herstart
  • Pods worden in volgorde gestart en gestopt
Bron: kubernetes.io – StatefulSets

Bouwblok: service

  • Pods komen en gaan, en hun ip-adres verandert. Een service geeft een groep pods een stabiel adres en een DNS-naam, en verdeelt de load.
  • Types:
    • ClusterIP (default): vast virtueel ip, enkel binnen de cluster
    • NodePort: bereikbaar op een vaste poort (30000–32767) van elke node
    • LoadBalancer: de cloudprovider maakt een (TCP-)load balancer met een extern ip. De implementatie hangt af van je provider.
  • Voor http(s) naar buiten: liever een Gateway (of Ingress), met veel meer mogelijkheden
Twee services die elk een groep pods op verschillende nodes bundelen

Service types

Schetsen van ClusterIP via een proxy, LoadBalancer en NodePort op poort 30000 van elke VM
Bron: joseluisgomez.com – Hands-on Kubernetes

Service: YAML


apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 8080
								
  • selector: naar welke pods gaat het verkeer? Alle pods met het label app: nginx.
  • port: de poort van de service
  • targetPort: de poort waarop de container luistert
  • Andere pods bereiken deze service via de DNS-naam my-service (in dezelfde namespace)

Bouwblok: Ingress en Gateway

Ingress

  • Lijkt op een service van het type LoadBalancer, maar met veel meer features: http(s), TLS offloading, routering op hostnaam en pad
  • Eén Ingress kan meerdere services bedienen
  • Extra opties via annotaties, die per implementatie verschillen
  • Bevroren: wordt niet verder ontwikkeld

Gateway API

  • De opvolger van Ingress, GA sinds 2023
  • Rollen apart: GatewayClass (provider), Gateway (platformteam), HTTPRoute (app-team)
  • Standaard ook header matching, rewrites, traffic splitting
  • Bij GKE: GatewayClass gke-l7-global-external-managed

Best practice: naar buiten via een Gateway, niet via een LoadBalancer per service

Gateway en HTTPRoute

gebruiker Gatewayload balancer, TLS platformteam HTTPRoutehost, pad, headers app-team Service: api Service: web /api / pod pod pod pod pod

Gateway en HTTPRoute: YAML


apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shop-gateway
spec:
  gatewayClassName: gke-l7-global-external-managed
  listeners:
  - name: http
    protocol: HTTP
    port: 80
								

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop
spec:
  parentRefs:
  - name: shop-gateway
  rules:
  - matches:
    - path: { type: PathPrefix, value: /api }
    backendRefs:
    - { name: api, port: 80 }
  - backendRefs:            # al de rest
    - { name: web-v1, port: 80, weight: 90 }
    - { name: web-v2, port: 80, weight: 10 }
								
  • De HTTPRoute hangt zich via parentRefs aan een Gateway
  • Met weight splits je het verkeer: hier gaat 10% naar een nieuwe versie (canary release)

Bouwblok: namespace

  • Een logische scheiding tussen projecten, klanten of omgevingen (dev, test, prod) binnen dezelfde cluster
  • Namen moeten uniek zijn binnen een namespace, niet over namespaces heen
  • Elke service krijgt automatisch een DNS-naam:
    
    service-naam.namespace.svc.cluster.local
    								
  • Opgelet: standaard geen beveiliging. Diensten zijn over namespaces heen bereikbaar. Afschermen doe je met NetworkPolicies, RBAC en ResourceQuota per namespace.

Labels & selectors: de lijm

Deployment met matchLabels app: nginx en een service met selector app: nginx die naar de labels in de pod-template verwijzen
Bron: datree.io – A Kubernetes guide for labels and selectors

Selectors kiezen ook nodes


apiVersion: v1
kind: Pod
metadata:
  name: cuda-test
spec:
  containers:
  - name: cuda-demo
    image: registry.k8s.io/cuda-vector-add:v0.1
    resources:
      limits:
        nvidia.com/gpu: 1
  nodeSelector:
    cloud.google.com/gke-accelerator: nvidia-l4
								
  • Nodes hebben ook labels (key: value), bv. het type GPU
  • De nodeSelector bepaalt op welke nodes deze pod mag komen
  • Fijnmaziger: node affinity, en taints & tolerations om nodes af te schermen

Secrets

  • Gevoelige gegevens (wachtwoorden, tokens, certificaten) los van de image en van je code bewaren
  • Opgelet: de waarden zijn enkel base64-gecodeerd, niet geëncrypteerd. Wie de secret mag lezen, kent het wachtwoord.
  • Encryptie at rest in etcd moet aan staan (bij managed clusters vaak standaard), en beperk de toegang met RBAC
  • Niet-gevoelige configuratie zet je in een ConfigMap

kubectl create secret generic db-user-pass \
    --from-literal=username=admin \
    --from-literal=password='1f2d1e2e67df'
secret/db-user-pass created
						

Een secret gebruiken


apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
stringData:   # leesbaar invoeren, anders base64
  username: "db-admin"
  password: "S3cr3tP@ssw0rd!"
								

apiVersion: v1
kind: Pod
metadata:
  name: app-pod-env
spec:
  containers:
  - name: my-app
    image: busybox
    command: ["sleep", "3600"]
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-credentials
          key: password
								

Secrets: best practices

  • Gebruik ze enkel als het nodig is. De meeste cloudomgevingen hebben een specifieke dienst voor secrets: Secret Manager (GCP), Secrets Manager (AWS), Key Vault (Azure).
  • Koppel die aan je cluster met de Secrets Store CSI driver of de External Secrets Operator
  • Nog beter: geen wachtwoord. Met Workload Identity krijgt een pod een eigen identiteit in de cloud, zonder sleutelbestand.
  • Nooit secrets in Git, in de image of in logs

Deel 5

Werking: kubectl, schalen, netwerken en storage

Klaarzetten van je omgeving

  • Een goede editor met YAML-ondersteuning (bv. VS Code met de Kubernetes-extensie)
  • kubectl, het commando om Kubernetes te beheren, en bij GKE ook de gke-gcloud-auth-plugin
  • De inloggegevens van je cluster ophalen

gcloud components install kubectl gke-gcloud-auth-plugin
gcloud container clusters get-credentials cluster --location europe-west1-d
kubectl get nodes
kubectl create namespace demo
						

Resources aanmaken

Imperatief: commando's


kubectl create deployment testdeploy \
    --image=nginx:1.29 --port=80 -n demo
								
  • Snel om te testen, maar niet reproduceerbaar
  • Met --dry-run=client -o yaml krijg je de YAML als vertrekpunt

Declaratief: YAML


kubectl apply -f deployment.yaml
kubectl apply -f ./k8s/   # hele map
								
  • Bestanden in Git: herhaalbaar en reviewbaar
  • apply opnieuw uitvoeren past enkel aan wat veranderd is

Resources bevragen

CommandoWat?
kubectl get pods -n testlijst van de pods in de namespace test
kubectl describe pods -n testalle details, met onderaan de events
kubectl logs pod -n testoutput van de container (-f om te volgen)
kubectl exec -it pod -n test -- sheen shell in de container
kubectl port-forward svc/service 8080:80 -n testtunnel van je pc naar de cluster
kubectl get events -n testwat gebeurde er recent?

'pods' kan je uiteraard vervangen door andere objecten: deployments, services, gateways, pvc…

Schalen

Handmatig


kubectl scale deployment web --replicas=5
								

Automatisch: HorizontalPodAutoscaler


kubectl autoscale deployment web \
    --min=2 --max=10 --cpu=60%
kubectl get hpa
								
  • Pods horizontaal: HorizontalPodAutoscaler op basis van CPU, geheugen of eigen metrics
  • Pods verticaal: VerticalPodAutoscaler past de requests aan
  • Nodes: de cluster autoscaler voegt nodes toe als pods op Pending blijven staan
  • Een HPA overschrijft handmatig schalen

Rolling updates

start v1 v1 v1 v1 stap 1 v2 v1 v1 v1 ready? → stap 2 v2 v2 v1 v1 ready? → klaar v2 v2 v2 v2

kubectl set image deployment/web web=registry/app:v2   # nieuwe versie
kubectl rollout status deployment/web                  # meekijken
kubectl rollout undo deployment/web                    # terug naar v1
						

Netwerken

  • Elke pod heeft een eigen ip-adres. Alle pods kunnen elkaar bereiken zonder NAT, ook over nodes heen.
  • Dat netwerk tussen de nodes komt van een CNI-plugin: Calico, Cilium, Flannel… of die van je cloudprovider
  • Een service krijgt een ClusterIP: een virtueel ip-adres dat verkeer verdeelt over de pods (via kube-proxy of eBPF)
  • Pods vinden services via DNS (CoreDNS): gebruik de servicenaam, nooit een pod-ip
  • Containers binnen dezelfde pod praten via localhost
  • NetworkPolicies werken als firewallregels tussen pods

Storage

  • Samen met ingress het onderdeel dat het meest afhangt van de implementatie van de vendor (via een CSI-driver)
  • Een PersistentVolumeClaim (PVC) = een aanvraag voor opslag van een bepaalde StorageClass (type: SSD, standaard…)
  • Het onderliggende PersistentVolume (PV) wordt bij cloudproviders automatisch aangemaakt: dynamic provisioning
  • Access modes:
    ReadWriteOncelezen/schrijven vanaf één node (meest voorkomend, bv. persistent disk)
    ReadWriteOncePodlezen/schrijven door één pod
    ReadOnlyManyenkel lezen, vanaf meerdere nodes
    ReadWriteManylezen/schrijven vanaf meerdere nodes: netwerkbestandssysteem nodig (bv. Filestore, EFS)
Overzicht: kubernetes.io – Persistent volumes

Storage: YAML


apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fastdisks
  resources:
    requests:
      storage: 8Gi
								

Zonder storageClassName krijg je de default class (kubectl get storageclass).

Met StorageClasses bied je zelf meerdere tiers aan:


apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fastdisks
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
volumeBindingMode: WaitForFirstConsumer
								

Demo

  • Google Cloud: een GKE-cluster aanmaken
  • Namespaces
  • De console (UI) van GKE
  • Een deployment en service aanmaken, schalen en een pod verwijderen (self-healing)

Demo!

Quiz: welk object?

Er moeten altijd 3 instanties van mijn API draaien Deployment met replicas: 3
Het wachtwoord van de databank meegeven Secret of beter: een secret manager
/api naar de ene service, de rest naar een andere Gateway + HTTPRoute (of Ingress)
Een logging-agent op elke node DaemonSet
Elke nacht om 2 uur een backup nemen CronJob
Een databankcluster met een eigen disk per replica StatefulSet of een operator

Deel 6

Verder

Verder…

  • CronJobs: pods op regelmatige tijdstippen uitvoeren (docs)
  • Operators: eigen objecten (CRD's) + een controller die de kennis van een beheerder automatiseert, bv. een PostgreSQL-cluster met backups en failover
  • Helm: de 'app store' van Kubernetes
  • GitOps: de cluster volgt automatisch wat in Git staat (Argo CD, Flux)
  • Autoscaling op events (KEDA) en slim node-beheer (cluster autoscaler, Karpenter)

Kubernetes als bouwblok

  • voor cloud independency: dezelfde YAML op GKE, EKS, AKS of on-premises
  • voor service mesh-architecturen: Istio, Linkerd, Cloud Service Mesh (mTLS, retries, observability tussen services)
  • voor serverless oplossingen: Knative. Cloud Run implementeert de Knative Serving API.
  • voor AI-workloads: GPU-nodes en schedulers voor training en inferencing

Extra: Helm

  • Een abstractielaag die een "app store" voor Kubernetes mogelijk maakt
  • Herbruikbare pakketten: charts, met een systeem voor templating (values)
  • Installeren, upgraden en terugrollen als één geheel

helm repo add prometheus-community \
    https://prometheus-community.github.io/helm-charts
helm install monitoring \
    prometheus-community/kube-prometheus-stack
								
De Helm client haalt een chart uit een chart repository en installeert die via de Kubernetes API server

Artifact Hub

Startpagina van Artifact Hub: find, install and publish Kubernetes packages
artifacthub.io

Compose, Kubernetes of serverless?

Docker ComposeKubernetes (GKE Standard)GKE AutopilotCloud Run
Hosts1zoveel je wilbeheerd door Googleonzichtbaar
Self-healingherstart op dezelfde hostjajaja
Autoscalingneepods en nodespods, nodes automatischook naar nul
Jij beheertde servernodes, upgrades, capaciteitenkel je workloadsenkel je container
Je betaalt per…servernode (VM) + clusteraangevraagde pod-resourcesgebruik
Flexibiliteitbeperktmaximaalgroothttp-containers en jobs

Samenvatting

Je wint

  • Self-healing en desired state
  • Schalen en updaten zonder downtime
  • Eén standaard bij alle cloudproviders
  • Een enorm ecosysteem

Je betaalt met

  • Complexiteit en een steile leercurve
  • Beheer: upgrades, nodes, security
  • Kosten van nodes die ook draaien als het stil is
  • Snelle evolutie: features komen en gaan

Kubernetes is een platform om platformen te bouwen

Zelf aan de slag

Begin je zoektocht naar info steeds in de officiële documentatie. Die is, in tegenstelling tot de honderden blogs over het onderwerp, steeds up-to-date. Geen overbodige luxe met een framework dat elke paar maanden nieuwe features krijgt…

Volgende stap: aan de slag in het labo!