Kubernetes Architectuur uitleg

Kubernetes Architectuur

Om Kubernetes te beheersen β€” en te slagen voor het CKA-examen β€” moet je begrijpen hoe de interne componenten samenwerken. Dit artikel legt de architectuur uit van de kleinste eenheid (een container) tot het volledige cluster, met diagrammen en concrete voorbeelden.

Het grote plaatje: control plane en worker nodes

Een Kubernetes cluster bestaat uit twee soorten machines: de control plane (de hersenen) en de worker nodes (de werkers). De control plane beheert de gewenste clusterstatus; de worker nodes draaien de daadwerkelijke applicatie-workloads.

[Diagram: Kubernetes cluster architectuur β€” control plane + worker node]

Control plane: API server, etcd, scheduler, controller manager | Worker node: kubelet, kube-proxy, container runtime, pods

Control plane componenten

API server β€” de centrale toegangspoort

De kube-apiserver is het enige component dat direct communiceert met de buitenwereld. Alle commando’s die je uitvoert via kubectl, alle aanvragen van applicaties, alle communicatie tussen interne componenten β€” alles gaat via de API server. Het is een RESTful HTTP-server die authenticatie, autorisatie en validatie uitvoert vΓ³Γ³r elke aanvraag wordt verwerkt.

# Elke kubectl-aanvraag raakt de API server
kubectl get pods
# Dit stuurt een GET /api/v1/namespaces/default/pods naar de API server

# De API server direct aanspreken (zelden nodig)
kubectl get --raw /api/v1/namespaces/default/pods | jq '.items[].metadata.name'

etcd β€” het geheugen van het cluster

etcd is een gedistribueerde key-value store en het enige persistente opslagmedium van Kubernetes. Alle clusterstatus β€” welke pods er zijn, welke nodes beschikbaar zijn, welke ConfigMaps er bestaan β€” staat in etcd. De API server schrijft naar en leest uit etcd; geen enkel ander component communiceert rechtstreeks met etcd.

# etcd-status controleren (op control plane node)
ETCDCTL_API=3 etcdctl member list \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# Backup maken (CKA-examenstof)
ETCDCTL_API=3 etcdctl snapshot save backup.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

Scheduler β€” intelligente workloadverdeling

De kube-scheduler bewaakt de API server op nieuwe pods zonder een nodeName en berekent op welke node die pod het beste kan worden geplaatst. Het houdt rekening met: beschikbare CPU en geheugen, NodeAffinity-regels, Taints en Tolerations, PodAntiAffinity en TopologySpreadConstraints. De scheduler schrijft de gekozen node terug naar de API server β€” de kubelet op die node pakt het daarna op.

Controller manager β€” de zelfherstellende motor

De kube-controller-manager bevat tientallen controllers die continu de gewenste clusterstatus vergelijken met de werkelijke status en bijsturen. De meest relevante:

  • Deployment controller β€” zorgt dat het juiste aantal replicas draait
  • ReplicaSet controller β€” beheert de individuele pod-instanties
  • Node controller β€” detecteert wanneer nodes onbereikbaar zijn
  • Service controller β€” beheert cloud-load balancers voor Services
  • Job controller β€” zorgt dat Jobs worden afgemaakt

Worker node componenten

kubelet β€” de node-agent

De kubelet draait op elke worker node en is de brug tussen de API server en de container runtime. Het bewaakt de API server voor pods die op zijn node zijn ingepland, en instrueert de container runtime om die pods te starten. Het rapporteert ook de nodestatus (CPU, geheugen, conditie) terug aan de API server.

# kubelet-status controleren
systemctl status kubelet

# kubelet-logs bekijken
journalctl -u kubelet -f

# Kubelet-configuratie
cat /var/lib/kubelet/config.yaml

kube-proxy β€” netwerken op node-niveau

De kube-proxy implementeert de netwerkregels op elke node zodat Services bereikbaar zijn. Wanneer je een Service aanmaakt, zorgt kube-proxy via iptables (of IPVS) dat verkeer naar het Service-IP wordt doorgestuurd naar de juiste pods, ook als die pods op andere nodes draaien.

Container runtime β€” CRI-O of containerd

De container runtime voert de daadwerkelijke containeroperaties uit: images downloaden, containers starten en stoppen, namespaces en cgroups instellen. Kubernetes communiceert met de runtime via de Container Runtime Interface (CRI). De meest gebruikte runtimes zijn CRI-O (standaard in OpenShift) en containerd (standaard in de meeste andere distributies).

De kleinste eenheid: van container naar pod naar deployment

Container

Een container is een geΓ―soleerd proces met eigen filesystem, netwerk en procestabel, gebaseerd op een image. Kubernetes beheert containers nooit direct β€” altijd via pods.

Pod

Een pod is de kleinste deploybare eenheid in Kubernetes. Een pod bevat één of meer containers die:

  • Hetzelfde netwerk delen (zelfde IP-adres)
  • Hetzelfde opslagvolume kunnen gebruiken
  • Als één eenheid worden gestart en gestopt
# Eenvoudige pod aanmaken
kubectl run nginx --image=nginx:1.25

# Pod-manifest
apiVersion: v1
kind: Pod
metadata:
  name: mijn-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 500m
        memory: 256Mi

ReplicaSet

Een ReplicaSet zorgt dat er altijd een bepaald aantal identieke pods draait. Als een pod crasht, maakt de ReplicaSet automatisch een nieuwe aan. Je gebruikt ReplicaSets vrijwel nooit direct β€” dat gaat via een Deployment.

Deployment

Een Deployment beheert een ReplicaSet en voegt rolling updates en rollback-mogelijkheden toe. Dit is de standaard manier om stateless applicaties te deployen.

# Deployment aanmaken
kubectl create deployment nginx --image=nginx:1.25 --replicas=3

# Rolling update uitvoeren
kubectl set image deployment/nginx nginx=nginx:1.26

# Rollout status volgen
kubectl rollout status deployment/nginx

# Terugdraaien
kubectl rollout undo deployment/nginx

# Deployment-manifest
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mijn-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mijn-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: mijn-app
    spec:
      containers:
      - name: mijn-app
        image: mijn-app:1.0.0

Netwerkcommunicatie: Services

Pods hebben vluchtige IP-adressen β€” ze kunnen op elk moment worden vervangen. Een Service geeft een stabiel IP-adres en DNS-naam voor een groep pods.

# Service types:

# ClusterIP (intern, standaard)
kubectl expose deployment mijn-app --port=80 --target-port=8080

# NodePort (bereikbaar op elk node-IP + poort)
kubectl expose deployment mijn-app --port=80 --type=NodePort

# LoadBalancer (cloud load balancer)
kubectl expose deployment mijn-app --port=80 --type=LoadBalancer

# DNS van een service (vanuit elke pod bereikbaar)
# mijn-app.default.svc.cluster.local

Configuratie en secrets

# ConfigMap β€” niet-gevoelige configuratie
kubectl create configmap app-config \
  --from-literal=LOG_LEVEL=debug \
  --from-literal=DB_HOST=postgres

# Secret β€” gevoelige data (base64-gecodeerd)
kubectl create secret generic db-secret \
  --from-literal=password=MijnWachtwoord

# In een pod gebruiken als environment variabelen
env:
- name: LOG_LEVEL
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: LOG_LEVEL
- name: DB_PASS
  valueFrom:
    secretKeyRef:
      name: db-secret
      key: password

Opslag: PersistentVolumes

# PersistentVolumeClaim aanmaken
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 10Gi
  storageClassName: fast-ssd

# In een pod gebruiken
volumes:
- name: data
  persistentVolumeClaim:
    claimName: data-pvc
volumeMounts:
- name: data
  mountPath: /data

De reconciliation loop: hoe Kubernetes zichzelf herstelt

Het centrale concept van Kubernetes is de control loop (reconciliation loop): elk component bewaakt continu het verschil tussen de gewenste staat (wat in etcd staat) en de werkelijke staat (wat er daadwerkelijk draait) en probeert dat verschil te corrigeren.

  1. Jij schrijft de gewenste staat: “ik wil 3 replica’s van nginx”
  2. De API server slaat dit op in etcd
  3. De Deployment controller detecteert: er zijn 0 pods, er zouden 3 moeten zijn
  4. De controller maakt een ReplicaSet aan
  5. De ReplicaSet controller maakt 3 pods aan (zonder nodeName)
  6. De Scheduler detecteert 3 pods zonder nodeName en kiest voor elke pod een node
  7. De kubelet op elke gekozen node detecteert de pod en start de container
  8. Als een pod crasht, begint de loop opnieuw bij stap 3

Dit is waarom Kubernetes zelfherstellend is: het werkt niet via directe opdrachten (“start deze container”), maar via gewenste toestanden die constant worden afgedwongen.

Relevantie voor certificeringen

  • CKA β€” alle componenten zijn examenstof: etcd-backup, kubelet troubleshooting, scheduler-gedrag
  • CKAD β€” pods, deployments, services, configmaps en persistent volumes
  • EX280/EX380 β€” OpenShift bouwt voort op deze Kubernetes-basis met extra componenten (Operators, Routes, SCCs)