Hoe werkt het?

Kubernetes dirigeert allemaal kleine microservices in de vorm van containers op basis van configuratiebestanden. Om je een indruk te geven hoe dit werkt lopen we deze onderdelen stap voor stap door.

Microservices

Zoals je traditioneel één applicatie hebt, wordt deze met gebruik van microservices opgesplitst. In die traditionele applicatie wordt misschien al gebruik gemaakt van plug-ins of modules. Zo heb je misschien een betaalmodule voor je winkel. In microservices worden dit aparte "micro" diensten, de plug-in wordt dus helemaal uit de applicatie gehaald en nu heb je 2 applicaties die onafhankelijk ontwikkeld kunnen worden: de winkel en de betaalapplicatie. Trek je dit door dan krijg je een hoop kleine onderdelen waar ontwikkelaars/-teams aan kunnen werken op grote schaal.

Microservices gaat dus vooral om logica in het ontwerp, het opsplitsen van je applicatie in losse diensten. Wil je hier meer over weten? Google heeft hier deze demo over gemaakt of maak een afspraak voor persoonlijk advies.

Containers

Om deze microservices te realiseren zijn containers een belangrijk onderdeel. Containertechnologie zorgt ervoor dat je meerdere (zelfs versies van) applicaties naast elkaar kan draaien op hetzelfde OS. Maar dat kan toch al zou je denken? Ja tot op zekere hoogte wel, maar de complexiteit om 6 python, php, C#, java en nodeJS versies naast elkaar te draaien is ons net wat te veel... Met containers daarentegen gaan we deze uitdaging lachend aan!

Een container is eigenlijk een klein OS gebaseerd op een image. Aan dit image kun je logica toevoegen, dit gebeurt door een configuratiebestand: de container file. Hier een voorbeeld uit de Docker-documentatie:

FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py

Met dit configuratiebestand wordt een nieuw image gemaakt, waarop weer door kan worden ontwikkeld. Dit werkt omdat alle wijzigingen worden opgeslagen, en deze efficiënt kunnen worden hergebruikt. Zo maakt het wordpress:latest image gebruik van het php:7.4-fpm image, deze maakt zelf dan weer gebruik van het debian:bullseye-slim image.

Om lokaal images te draaien raden wij Docker aan. Testen met een basis WordPress installatie doe je dan zo:

docker run --name my-1st-wordpress -p 8080:80 -d wordpress
# ga naar http://localhost:8080 om het resultaat te zien

Configuratie

Eigenlijk valt de container dus ook al onder de configuratiebestanden met de container file. Dit gaat echter over wat de container bevat. De volgende configuratiebestanden gaan over hoe de container gebruikt wordt.

Voor we naar Kubernetes gaan, nog een kleine tussenstop bij Docker. Docker heeft namelijk een tool waarmee je microservices lokaal al erg goed kan laten zien, het heet docker-compose. Je kunt WordPress in één container uitrollen zoals je eerder hebt gelezen, maar je kunt ook de database loskoppelen als aparte dienst. Hier een voorbeeld daarvan uit de docker-compose documentatie:

version: "3.9"
    
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}

Dit YAML-bestand bevat 2 services (DB, WordPress) met allebei een volume waar de gebruikersdata van WordPress en MySQL op bewaard blijven. YAML-bestanden zijn erg te vergelijken met JSON, alleen op basis van inspringing. In dit bestand staat hoe dit gekoppeld is en door environment variabelen geconfigureerd is.

In Kubernetes is dit iets minder overzichtelijk maar minstens zo krachtig! Kubernetes kun je zien als docker-compose-as-a-service met talloze uitbreidingen. Kubernetes werkt ook met YAML-bestanden. Een voorbeeld van een pod-configuratiebestand:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

Hopelijk kun je uit bovenstaand voorbeeld al opmaken dat dit om een nginx-container gaat. Tevens ben je vooral wat wijzer geworden over het belangerijkste onderdeel van Kubernetes: de containers. Alle onderdelen van Kubernetes worden met soortgelijke configuratiebestanden als hier boven aangestuurd. Om je verder op gang te helpen met het uitrollen van jou eigen applicatie hebben we een tutorial gemaakt.