3n.nl / haven-lab / referentie

Eén plaat, vakje voor vakje — en wat er verandert als je schaalt

Dit is de referentie bij het Haven+ thuislab: een complete Haven-omgeving op één gaming-pc. Deel 1 loopt de plaat van onder naar boven door en legt elk vakje uit. Deel 2 is de catalogus: elk component, zijn rol, de open standaard waarop het leunt en waar het in git staat. Deel 3 zet vier architecturen naast elkaar — van deze ene pc tot meerdere infraproviders met failover — en laat zien wat er dan wél en níet verandert. De rode draad: desired state. Alles komt uit git, en dat is precies wat schalen en verhuizen mogelijk maakt zonder herbouw.

> stand 11 oktober 2026 · experiment op een gamecomputer, geen productieadvies · bron: nixos_eigen_hardware1

de plaat

Haven-lab op havenpc

Vier lagen op elkaar, en rechts de strook "buiten de pc". De architectuurplaat op de hoofdpagina toont hetzelfde systeem schematisch; deze versie noemt de componenten bij naam en versie zoals ze nu draaien.

Laag 0 — havenpc (NixOS 26.05, Firebreather i7-14700KF, 32 GB, boot van Samsung T7 via USB 3) Incus (VM-modus, bridge havenbr0 10.42.0.0/24, NAT) NFS-export /srv/haven/nfs → StorageClass "nfs" (RWX) chrony (NTP) · nftables · autoUpgrade elke 10 min uit GitHub Tailscale subnet-router: 10.42.0.0/24 het tailnet in Wake-on-LAN (enp4s0) · Windows op de NVMe blijft onaangeraakt rick3n/nixos_eigen_hardware1 · hosts/havenpc Laag 1 — Talos 1.13.10 / Kubernetes v1.36.2 (zes Incus-VM's, zones a/b/c, Flannel) cp1 · cp2 · cp3 2 vCPU · 4 GiB · etcd · VIP .10 worker1 · 2 · 3 4 vCPU · 5 GiB · .21–.23 Basislaag (Flux): MetalLB 10.42.0.200–250 · csi-driver-nfs (default SC) · metrics-server Talos-eigenaardigheden: Pod Security "baseline" → istio-system en metallb-system op privileged Laag 2 — Haven+ platformdiensten (VNG gitops-flux, fork rick3n/haven-gitops · clusters/havenpc) Toegang Istio ambient + Gateway API cert-manager · CA "haven-ca" Identiteit Keycloak · realm havenplus groepen per rol (beheer, loket, …) Observability Alloy → Loki · Mimir · Tempo Grafana (SSO) · Garage (S3) Beleid & data Kyverno (PSS restricted) CloudNative-PG · sealed-secrets Beheer Flux (GitOps, SOPS/age) Headlamp · Haven CLI Nog uit (geheugen): Pinniped · OpenBao · External Secrets · Velero · Falco · Trivy · ECK · OpenCost Alles wat hier staat komt uit git; Flux reconcileert elke 5–10 min. Secrets staan versleuteld in de repo (age-sleutel alleen op havenpc). Laag 3 — Common Ground-toepassingen (tenants/openzaak) Open Zaak 1.30 Zaken · Catalogi · Documenten · Autorisaties Open Notificaties 1.16 kanalen zaken, documenten, … Later: Open Formulieren (loket) · Objecten API · MijnBureau (na 64 GB) Demo: toezichthouder — melding → signaal → vordering, forensisch gescheiden van behandeling Gebruikers (tailnet) hx90, telefoon · *.haven.3n.nl → 10.42.0.200 https via gateway GitHub (desired state) haven-gitops · nixos_eigen_hardware1 Flux pull elke 5 min autoUpgrade (NixOS) elke 10 min
Groen zijn de twee pull-lussen: gebruikers komen binnen via Tailscale op de gateway, en zowel het cluster (Flux) als de host (NixOS autoUpgrade) halen hun gewenste toestand zelf uit GitHub. Niemand zet iets "op de machine".

leeswijzer

Hoe je de plaat leest

De plaat is een stapel van vier lagen, met rechts een strook "buiten de pc". Elke laag levert iets aan de laag erboven en weet niets van de laag eronder: de toepassingen kennen alleen Kubernetes, Kubernetes kent alleen zes machines, en de host weet niet wat er in de VM's draait. Die onwetendheid is het hele punt — het is wat je straks laat verhuizen zonder dat de bovenliggende lagen het merken.

Twee pijlen rechts zijn belangrijker dan alle vakjes samen. Flux pull elke 5 min en autoUpgrade elke 10 min: beide lagen halen hun gewenste toestand zelf uit GitHub. Er is geen beheerder die iets "op de machine zet"; er is een repo, en machines die zich daarnaar vormen. Dat heet desired state, en het is de reden dat dit lab op een leeg cluster in een paar uur opnieuw op te bouwen is — en dat de schaalpaden in deel 3 geen herbouw zijn maar een extra map in git.

Kleuren: grijs is de host, groenblauw het cluster, blauw het platform, paars de toepassingen, oker alles wat van buiten komt.

laag 0

Laag 0 — de host: havenpc

Eén fysieke machine: een gaming-pc (i7-14700KF, 32 GB, binnenkort 64) die van een externe Samsung T7 boot. Het besturingssysteem is NixOS: de hele machine — pakketten, services, firewall, gebruikers — staat als één declaratieve configuratie in git (hosts/havenpc/). Windows op de interne NVMe blijft onaangeraakt; de pc is 's avonds nog gewoon een spelcomputer.

Incus (VM-modus, bridge havenbr0 10.42.0.0/24, NAT)

De virtualisatielaag. Incus draait zes KVM-virtuele machines en geeft ze een eigen netwerk (havenbr0, 10.42.0.0/24) met NAT naar buiten.

Waarom
Haven eist drie control-plane-nodes, drie workers en meerdere zones. Op één machine haal je dat alleen met VM's. Incus is declaratief te beheren vanuit NixOS (virtualisation.incus.preseed): profielen, netwerk en opslagpool staan in git.
Zonder dit
Geen cluster. Dit is de "cloud" van het lab: wat een echte provider als IaaS levert, levert Incus hier.
In git
hosts/havenpc/incus.nix; VM's zelf via scripts/haven-vms.sh

NFS-export /srv/haven/nfs → StorageClass "nfs" (RWX)

Gedeelde opslag voor het cluster. De host exporteert een map; in het cluster wordt die via csi-driver-nfs een StorageClass die ReadWriteMany-volumes kan uitdelen.

Waarom
Haven-check "ReadWriteMany persistent volumes support". Open Zaak heeft het nodig voor zijn documentenopslag (meerdere pods, één map).
Let op
De export mag geen fsid=0 hebben (dan is de map de pseudoroot en mount de driver niets). In een echte omgeving vervang je dit door NFS van de provider, Ceph/Longhorn, of objectopslag.
In git
hosts/havenpc/services/nfs.nix

chrony · nftables · autoUpgrade elke 10 min uit GitHub

Tijd, firewall en de uitrol-lus van de host.

chrony
Tijdsynchronisatie. Kubernetes en vooral etcd zijn gevoelig voor klokverschil; de VM's volgen de host.
nftables
De firewall van de host: alleen ssh, Tailscale en wat het cluster nodig heeft.
autoUpgrade
Elke tien minuten git pull + nixos-rebuild switch met een read-only deploy key. Een push naar main is de uitrol; een slechte commit rol je terug door te reverten. Dit is de eerste van de twee lussen.

Tailscale subnet-router: 10.42.0.0/24 het tailnet in

De enige toegang. De host adverteert het VM-netwerk in het tailnet, zodat je laptop en telefoon *.haven.3n.nl (→ 10.42.0.200) kunnen bereiken zonder dat er iets op internet open staat.

Waarom
Haven-check "private networking topology", en gewoon verstandig: geen poorten naar buiten, identiteit op netwerkniveau (WireGuard, apparaat-gebonden sleutels), toegangsregels in de Tailscale-ACL.
In de schaalpaden
Dit is de plek waar straks een echte WAN-koppeling komt: site-to-site VPN, een provider-peering, of simpelweg Tailscale op elk cluster.

Wake-on-LAN (enp4s0) · Windows op de NVMe blijft onaangeraakt

Praktische randzaken. De NUC in de meterkast kan de pc wakker maken; de interne schijf is nooit aangeraakt, dus de pc blijft ook een gewone pc.

laag 1

Laag 1 — het Haven-cluster: Talos en Kubernetes

Zes VM's draaien Talos Linux 1.13 en vormen samen Kubernetes v1.36. Talos is een besturingssysteem dat alleen Kubernetes kan: geen shell, geen ssh, geen pakketbeheer — alleen een API (talosctl). Alles wat je erop wilt veranderen gaat via een machineconfiguratie die in git staat (haven/talos/, gegenereerd door talhelper). Dat is de reden dat de Haven-check "node hardening" groen is.

cp1 · cp2 · cp3 — 2 vCPU · 4 GiB · etcd · VIP .10

De control plane: de hersenen van het cluster. Elk draait de API-server, scheduler, controller-manager en een lid van etcd, de database waarin de hele clusterstaat ligt.

Waarom drie
etcd werkt met meerderheidsbesluit (quorum). Met drie leden mag er één uitvallen; met twee niet. Haven eist er daarom drie.
VIP .10
Eén virtueel adres (10.42.0.10) dat altijd bij een levende control-plane-node hoort; kubectl praat daartegen, niet tegen een specifieke machine.
Geleerd
Op 3 GiB kreeg etcd time-outs; 4 GiB is het minimum. Een trage schijf (USB 2.0) maakte etcd "overloaded" — de control plane is gevoeliger voor I/O dan voor CPU.

worker1 · 2 · 3 — 4 vCPU · 5 GiB · .21–.23

De spieren. Alle platformdiensten en toepassingen draaien hier als pods; de control plane draait zelf niets van de workload.

Zones a/b/c
Elke worker en elke control-plane-node draagt een label topology.kubernetes.io/zone. Het cluster ziet drie beschikbaarheidszones en spreidt replica's eroverheen. Op één pc is dat een afspraak; in de schaalpaden wordt het een echte kast, een ander datacenter of een andere provider — zonder dat het cluster anders geconfigureerd hoeft te worden.
Geleerd
Zonder resource-requests stapelt de scheduler alles op de eerste worker en gaat die node thrashen. 3×5 GiB is de grens; de uitbreiding naar 64 GB maakt er 3×10 van.

Basislaag (Flux): MetalLB · csi-driver-nfs · metrics-server

Wat een cloudprovider normaal "gratis" meelevert en een kaal cluster mist.

MetalLB
Deelt LoadBalancer-adressen uit (10.42.0.200–250) en beantwoordt ARP voor die adressen (L2-modus). Bij een provider vervangt de cloud-loadbalancer dit.
csi-driver-nfs
De StorageClass "nfs" (standaard) op de export van de host.
metrics-server
CPU- en geheugencijfers per pod, voor kubectl top en autoscaling. Haven-check.
Flux-beheerd
Oorspronkelijk via helmfile, nu overgenomen door Flux (infrastructure/havenpc-base/): ook de basislaag is desired state.

Talos-eigenaardigheden: Pod Security "baseline"

Talos zet standaard Pod Security Admission op baseline voor alle namespaces. Componenten die privileged containers nodig hebben (Istio's CNI en ztunnel, MetalLB's speaker) starten dan niet. De namespaces istio-system en metallb-system staan daarom expliciet op privileged.

Ook geleerd: Talos-systeemextensions in een Incus-VM zijn riskant. De qemu-guest-agent-extension startte nooit, Talos zag de boot als mislukt en herstartte elke 71 minuten. Het image is nu leeg (geen extensions).

laag 2

Laag 2 — Haven+ platformdiensten

Haven zegt hoe het cluster eruit moet zien; Haven+ is de VNG-referentie voor wat er standaard op het cluster hoort: toegang, identiteit, observability, beleid, data en beheer — met OpenID Connect, OpenTelemetry en de Gateway API als gemeenschappelijke taal. Het lab draait een fork van VNG's gitops-flux (rick3n/haven-gitops), met een eigen overlay per cluster (clusters/havenpc/). Flux leest die repo en maakt het cluster er gelijk aan.

Toegang

Istio ambient + Gateway API

De voordeur. Eén gateway op 10.42.0.200 beëindigt TLS en routeert op hostnaam (HTTPRoute) naar de juiste dienst. Ambient-modus betekent: geen sidecar per pod, maar een node-agent (ztunnel) die verkeer tussen pods versleutelt (mTLS) zonder dat toepassingen het merken.

Standaard
Kubernetes Gateway API — leverancieronafhankelijk; Istio is inwisselbaar voor Envoy Gateway, Cilium of een cloud-gateway.
In git
infrastructure/istio*/overlays/havenpc; het LB-adres via metallb.io/loadBalancerIPs.

cert-manager · CA "haven-ca"

Automatische certificaten. In het lab tekent een eigen CA een wildcard voor *.haven.3n.nl; de root is op de hx90 en de telefoon geïmporteerd. Bij een publiek domein wisselt dezelfde component naar Let's Encrypt of een PKIoverheid-issuer.

Haven-check
"Automated HTTPS certificate provisioning".
Let op
De CA zit niet in de truststores van de containers; koppelingen tussen pods lopen daarom in-cluster over http (*.svc), de buitenkant over https.

Identiteit

Keycloak · realm havenplus · groepen beheer, loket, behandelaar, forensisch

Eén identiteit voor alles met een browser. Open Zaak, Open Notificaties, Grafana en de werkplek zijn OIDC-clients van realm havenplus; groepslidmaatschap (groups-claim) bepaalt de rol in elke toepassing. De realm zelf — groepen, gebruikers, clients — komt uit git (realm-import), de wachtwoorden en client-secrets uit SOPS.

Rol in het ontwerp
Keycloak is de brug tussen mensen en API-clients: de werkplek vertaalt een groep naar een ZGW-client met zijn autorisaties. In productie federeert Keycloak naar de IdP van de organisatie (Entra ID, DigiD via een broker, eHerkenning) zonder dat de toepassingen veranderen.
Nog uit
Pinniped (OIDC voor kubectl) — geheugen.

Observability

Alloy → Loki · Mimir · Tempo; Grafana (SSO); Garage (S3)

Eén logstroom, één metricsstroom, één tracesstroom. Alloy draait op elke node en verzamelt logs, metrics en OpenTelemetry-traces van alle pods; Loki bewaart logs, Mimir metrics, Tempo traces; Grafana toont ze — met Keycloak-login. Garage is de S3-objectopslag waar Loki en Mimir hun data in zetten.

Haven-check
"Log aggregation is running".
Waarom het ertoe doet
In de demo zie je in Loki de 403's van de behandelaar op de vorderingszaak; dat is het bewijs dat de scheiding technisch is, uit de logs van het platform en niet uit een scherm van de toepassing.
In productie
Garage wordt de S3 van de provider; de rest blijft gelijk.

Beleid en data

Kyverno (PSS restricted)

Beleid als code: admission-regels die bijvoorbeeld privileged containers of ontbrekende resource-limieten tegenhouden (Pod Security Standards "restricted"). In het lab draait alleen de admission-controller, met failurePolicy: Ignore — een onbereikbare webhook mag Flux en MetalLB niet gijzelen. Na de geheugenuitbreiding komen background-, reports- en cleanup-controller terug.

CloudNative-PG · sealed-secrets

CloudNative-PG is de PostgreSQL-operator: elke toepassing krijgt een eigen Cluster-object (Open Zaak op PostGIS, Keycloak, Grafana), met automatische failover tussen replica's en back-up naar S3 als je dat aanzet. Dit is ook de component die in deel 3 de data over locaties repliceert.

Sealed-secrets zit in de Haven+-referentie; het lab gebruikt SOPS/age (secrets versleuteld in de repo, sleutel alleen op havenpc). Sealed-secrets draait mee maar wordt niet gebruikt.

Geleerd
De CNPG-operator had een liveness-probe van 1 seconde; onder belasting werd hij om de 40 s gekilled en blokkeerde zijn webhook elke wijziging aan databases. Probes verruimd in de overlay.

Beheer

Flux (GitOps, SOPS/age) · Headlamp · Haven CLI

Flux is de tweede lus: elke vijf minuten haalt het rick3n/haven-gitops op, ontsleutelt secrets met de age-sleutel en past alles toe — inclusief zichzelf. Headlamp is de cluster-UI (met Flux-plugin). De Haven CLI doet de compliance-check: haven check = 15/15.

Volgorde
Flux-Kustomizations hebben dependsOn: cluster-resources → kyverno → cert-manager → istio → … → tenants. Zo komt een leeg cluster in de goede volgorde op.
Nog uit (geheugen)
Pinniped, OpenBao (secrets-kluis), External Secrets, Velero (back-up), Falco (runtime-detectie), Trivy (scans), ECK, OpenCost. Allemaal in de referentie; allemaal een regel in clusters/havenpc/infrastructure/kustomization.yaml.

laag 3

Laag 3 — Common Ground-toepassingen

Toepassingen zijn tenants: een namespace met een Flux-Kustomization, eigen database, eigen secrets, eigen route op de gateway. Ze gebruiken het platform (identiteit, database-operator, S3, gateway) en kennen elkaar alleen via de standaard-API's.

Open Zaak 1.30 — Zaken · Catalogi · Documenten · Autorisaties

Het zaakregister: de referentie-implementatie van de ZGW-API's (Zaken, Documenten, Catalogi, Besluiten, Autorisaties). Alles wat de demo laat zien — zaaktypen, vertrouwelijkheid, autorisaties per API-client, de 403 — is gedrag van deze API's, niet van een UI.

Desired state
Catalogus, zaaktypen, API-clients en demodata komen uit één script dat als Flux-Job draait (tenants/openzaak/); het eindigt met een test die faalt als de scheiding niet klopt.
Koppelingen
Keycloak (OIDC voor de admin), CNPG (PostGIS), NFS (documenten), Open Notificaties (gebeurtenissen).

Open Notificaties 1.16 — kanalen zaken, documenten, …

De gebeurtenissenbus van Common Ground: toepassingen abonneren zich op kanalen en krijgen een webhook als er een zaak, status of document bijkomt. Open Zaak publiceert erop; later luistert bijvoorbeeld een loket of een archiefcomponent mee.

Werkplek (demo-UI)

Een kleine rollen-UI: inloggen via Keycloak, en de groep bepaalt met welke ZGW-client de werkplek praat. Voegt geen autorisatie toe — wat Open Zaak weigert, laat de werkplek als 403 zien. Dit is bewust geen zaakafhandelcomponent; het bestaat om de API-scheiding zichtbaar te maken.

Later: Open Formulieren · Objecten API · MijnBureau

Open Formulieren als echt loket (stap 1 van de demo is nu gescript), Objecten API voor "onderneming" als object, MijnBureau (de BZK-werkplek) na 64 GB. Elk ervan is weer een map onder tenants/.

buiten de pc

Buiten de pc — de twee lussen

Gebruikers (tailnet): hx90, telefoon · *.haven.3n.nl → 10.42.0.200

Alle gebruikersverkeer komt via Tailscale binnen op de Istio-gateway. DNS voor *.haven.3n.nl wijst naar het LB-adres; de NUC is de DNS van het tailnet.

GitHub (desired state): haven-gitops · nixos_eigen_hardware1

Twee repo's, twee lussen. nixos_eigen_hardware1 is de host (en de Talos-configuratie); haven-gitops is alles in het cluster. Beide worden gelezen, nooit geschreven, door de machines. Secrets staan erin, versleuteld; de sleutel staat niet in git.

Wat handwerk blijft
De bootstrap: schijf partitioneren, deploy key, age-sleutel + het Flux-secret, flux install, tailscale up, een DNS-record. Daarna is alles een push.

catalogus

Componentencatalogus

Alles op de plaat, met rol, de open standaard of het protocol waarop het leunt (dat is wat het inwisselbaar maakt), waar het in git staat en de status in het lab.

ComponentLaagRolStandaard / protocolIn gitLab
NixOS0Declaratief besturingssysteem van de hostNix-flakehosts/havenpc/aan
Incus0KVM-virtualisatie, netwerk en opslagpool voor zes VM'sIncus REST-APIhosts/havenpc/incus.nixaan
NFS-server0RWX-opslag voor het clusterNFSv4.1hosts/havenpc/services/nfs.nixaan
Tailscale0Enige toegangspad; subnet-router voor 10.42.0.0/24WireGuardhosts/havenpc/ + ACL in Tailscaleaan
chrony, nftables, autoUpgrade0Tijd, firewall, uitrol-lus van de hostNTP; nftables; githosts/havenpc/aan
Talos Linux1Onveranderlijk node-OS, alleen APITalos machineconfighaven/talos/ (talhelper)1.13.10
Kubernetes1Containerorkestratie; 3 cp + 3 workers, 3 zonesCNCF-conformant (Talos v1.36 in het register)idemv1.36.2
etcd1Clusterstaat, quorum over drie control-plane-nodesRaftdoor Talosaan
Flannel1Pod-netwerk (CNI)CNI, VXLANTalos-standaardaan
MetalLB1LoadBalancer-adressen (L2)Kubernetes Service type LoadBalancerinfrastructure/havenpc-base/metallbaan, frr-k8s uit
csi-driver-nfs1StorageClass "nfs", RWXCSIinfrastructure/havenpc-base/csi-driver-nfsaan
metrics-server1Resource-metrics per pod/nodeKubernetes metrics APIinfrastructure/havenpc-base/metrics-serveraan
Istio (ambient)2Gateway, routering, mTLS tussen podsGateway API, mTLSinfrastructure/istio*/overlays/havenpcaan
cert-manager2Certificaten, eigen CA haven-caACME / X.509infrastructure/cert-manager/config/overlays/havenpcaan
Keycloak (+ operator)2Identiteit, SSO, groepen → rollenOpenID Connect, SAMLinfrastructure/keycloak/instances/overlays/havenpcaan
Alloy2Verzamelt logs, metrics, traces op elke nodeOpenTelemetry, Prometheusinfrastructure/alloy/overlays/havenpcaan
Loki / Mimir / Tempo2Opslag van logs / metrics / tracesLogQL, PromQL, OTLPinfrastructure/{loki,mimir,tempo}/…aan
Grafana (+ operator)2Dashboards, SSOOIDCinfrastructure/grafana/config/overlays/havenpcaan
Garage2S3-objectopslag voor Loki/MimirS3-APIinfrastructure/garage/config/overlays/havenpcaan
Kyverno2Beleid als code (PSS)Kubernetes admissioninfrastructure/kyverno/*/overlays/havenpcalleen admission
CloudNative-PG2PostgreSQL-operator, failover, back-up, replicatiePostgreSQL streaming replicationinfrastructure/cloudnative-pg/overlays/havenpcaan
sealed-secrets2Secrets in git (referentie)—infrastructure/sealed-secrets/…draait, ongebruikt (SOPS)
Flux2GitOps-lus van het cluster, SOPS-decryptiegit, Kustomize, Helm, SOPS/ageclusters/havenpc/2.8.8, zelfbeheerd
Headlamp2Cluster-UI met Flux-pluginKubernetes APIinfrastructure/headlamp/overlays/havenpcaan
Haven CLI2Compliance-check (15 checks)—~/bin/haven op havenpc15/15
Pinniped, OpenBao, External Secrets, Velero, Falco, Trivy, ECK, OpenCost2kubectl-OIDC, kluis, secrets-sync, back-up, detectie, scans, Elastic, kostenOIDC, KMS, S3, …in de referentie; uitgezet in clusters/havenpc/infrastructure/kustomization.yamluit (geheugen)
Open Zaak3Zaakregister: ZGW-API'sZGW-API's (VNG), OIDCtenants/openzaak/1.30
Open Notificaties3GebeurtenissenbusNotificaties API (VNG)tenants/openzaak/1.16
Werkplek3Rollen-UI op de ZGW-API'sOIDC, ZGW-JWTtenants/openzaak/werkplek/demo
Open Formulieren, Objecten API, MijnBureau3Loket, objecten, werkplek-suiteZGW, Objecten API—na 64 GB

schaalpaden

Vier schaalpaden: van één pc naar meerdere infraproviders

De vraag die het lab moet beantwoorden is niet "kan het op één pc", maar "wat verandert er als het niet meer op één pc hoeft". Het antwoord is: minder dan je denkt, en precies de dingen die je wilt kunnen veranderen. Hieronder vier stadia. In elk stadium zijn laag 2 en 3 — het platform en de toepassingen — dezelfde git-mappen. Wat verandert is laag 0 en 1: wie de machines levert, en hoeveel clusters er zijn.

1 · Eén pc (nu)havenpc · NixOS · Incus · NFS · Tailscale zone a (afspraak)zone b (afspraak)zone c (afspraak) cp1cp2cp3 worker1worker2worker3 één etcd-quorum · één NFS · één stroomkabel · Haven 15/15 · Haven+ · Open Zaak beschikbaarheid: de pc zelf · soevereiniteit: volledig
Alles op één machine. Drie zones zijn labels; valt de pc uit, dan valt alles uit. Goed voor leren, demonstreren en als blauwdruk — niet voor dienstverlening.
2 · Eigen cluster op meerdere machines (on-premises) machine / kast Amachine / kast Bmachine / kast C cp · zone acp · zone bcp · zone c workerworkerworkerworkerworkerworker schijven (Ceph)schijvenschijven gerepliceerde opslag · MetalLB over een echte switch · UPS per kast beschikbaarheid: één machine mag uitvallen · soevereiniteit: volledig in git: hosts/* × 3, talconfig met echte nodes, StorageClass ceph; laag 2+3 ongewijzigd
Dezelfde zes rollen, maar elke zone is nu een echte machine (of kast, of ruimte). Incus kan blijven (VM per rol) of verdwijnen (Talos direct op het ijzer). Opslag wordt gerepliceerd: Ceph (Rook) of Longhorn in plaats van één NFS. Alles in laag 2 en 3 is letterlijk dezelfde git-map.
3 · Gesplitst over infraproviders (actief / stand-by) On-premiseseigen ijzer, eigen sleutels EU-providerVM's of managed Kubernetes Haven-cluster A · 3 cp · 3 wkHaven-cluster B · 3 cp · 3 wk Haven+ · clusters/onpremHaven+ · clusters/eu Open Zaak (actief)Open Zaak (stand-by, replica) PostgreSQL-replicatie (CNPG) · S3-replicatie · versleuteld één git-repo, twee clusters-mappen · Flux op elk cluster · DNS wijst naar A beschikbaarheid: een locatie mag uitvallen · soevereiniteit: NL/EU, eigen sleutels in git: clusters/eu/ erbij (gateway-adres, StorageClass, S3-endpoint); laag 3 ongewijzigd
Twee complete Haven-clusters, elk met Flux en elk uit dezelfde repo. Alleen de map clusters/<naam>/ verschilt: LB-adres, StorageClass, S3-endpoint, DNS-naam. Data loopt als replica naar de tweede locatie. Bij uitval wordt B actief: DNS om, replica promoveren.
4 · Multi-cloud met failover en behoud van soevereiniteit Eigen capaciteit EU-provider Hyperscaler, NL-regio Haven-clusterHaven-clustermanaged Kubernetes Haven+Haven+Haven+ toepassingen (actief)toepassingen (actief)leeg; alleen bij calamiteit geen klantdata in rust buiten EU-jurisdictie; wel rekencapaciteit bij nood Boven de clusters, in eigen beheer:git · sleutels (SOPS/KMS) · identiteit (Keycloak) · DNS/GSLB · back-up buiten elke provider beschikbaarheid: een provider mag uitvallen · soevereiniteit: data en sleutels blijven van jou in git: clusters/<provider>/ per cluster; laag 2+3 ongewijzigd; exit = map verwijderen
Hetzelfde patroon, nog een keer herhaald. Elk cluster is Haven-compliant en dus uitwisselbaar; de hyperscaler levert alleen rekencapaciteit en krijgt geen data in rust. Wat boven de clusters hangt — git, sleutels, identiteit, DNS, back-up — staat bij geen enkele provider. Dat is wat soevereiniteit hier concreet betekent.

Wat verandert er per stadium, en wat niet

1 · Eén pc2 · Eigen cluster3 · Gesplitst4 · Multi-cloud
Laag 0 (host)NixOS + Incus op één pcNixOS/Talos op 3+ machines+ VM's of managed K8s bij een EU-provider+ managed K8s bij een hyperscaler, NL-regio
Laag 1 (cluster)6 VM's, zones = labelszones = machines/kasten; Ceph/Longhorntwee clusters, elk 15/15drie of meer clusters, elk 15/15
Laag 2 (Haven+)dezelfde infrastructure/-mappen; per cluster alleen een overlay met adres, StorageClass, S3-endpoint
Laag 3 (toepassingen)dezelfde tenants/-mappen; per cluster alleen wie actief is en waar de database-replica staat
OpslagNFS op de hostgerepliceerd over machinesgerepliceerd over locaties (CNPG, S3)gerepliceerd; back-up bij een derde partij of eigen kluis
ToegangTailscaleTailscale of eigen WANDNS wijst naar de actieve; VPN tussen locatiesGSLB/anycast of DNS-failover; provider-peering
Wat mag uitvallennietséén machineéén locatieéén provider
SoevereiniteitvolledigvolledigNL/EU; eigen sleutelseigen sleutels, identiteit, git en back-up; hyperscaler zonder data in rust
Wat erbij komt in git—hosts/*, talconfigclusters/eu/clusters/<provider>/ per cluster
Wat je ervoor moet oefenenherbouw op een leeg clusteréén machine uitzettenDNS omzetten, replica promovereneen hele provider "verliezen" en terugkomen
De rode draad. Haven maakt een cluster uitwisselbaar: elke Haven-compliant omgeving — eigen ijzer, een Nederlandse of Europese provider, een hyperscaler — kan dezelfde Haven+-laag en dezelfde toepassingen dragen. GitOps maakt die uitwisselbaarheid herhaalbaar: een nieuwe locatie is een nieuwe map in dezelfde repo, geen project. Samen betekenen ze dat je schaalt, verhuist en terugkeert zonder herbouw. Het lab op één pc bewijst de onderste helft van dat verhaal; de bovenste helft (replicatie, failover) is ontwerp, nog niet gebouwd.

failover

Calamiteit en failover: hoe het dan gaat

Neem stadium 3 of 4 en laat een locatie wegvallen — stroom, netwerk, een provider die een regio sluit, een juridische reden om ergens weg te moeten. Wat er dan gebeurt, in de volgorde waarin het moet:

  1. Vaststellen, niet raden. Observability loopt op élk cluster, en de dashboards van het overlevende cluster tonen dat de ander weg is. Besluit om over te schakelen is een menselijk besluit (of een vooraf afgesproken automatische, met een drempel).
  2. Data. De PostgreSQL-replica op het overlevende cluster wordt gepromoveerd tot primary (CNPG: één commando of een wijziging in git). Objectopslag was al gerepliceerd. Wat je verliest is hooguit de laatste seconden tot minuten (RPO) — afhankelijk van synchrone of asynchrone replicatie, en dat is een keuze per dataset: zaken synchroon, logs asynchroon.
  3. Toepassingen. Flux op het overlevende cluster zet de tenants op "actief" (in stadium 3 draaiden ze al als stand-by). Geen installatie: de gewenste toestand stond er al, alleen de schakelaar gaat om.
  4. Verkeer. DNS (of GSLB) wijst naar de gateway van het overlevende cluster. Met korte TTL's duurt dat minuten (RTO).
  5. Identiteit. Keycloak draait per cluster, met dezelfde realm uit git en gefedereerd naar de IdP van de organisatie; gebruikers loggen op dezelfde manier in. Sessies vervallen, rechten niet.
  6. Terug. Als de locatie terugkomt, wordt zij replica van de nieuwe primary; daarna kun je terugschakelen of de rollen laten zoals ze zijn. Omdat alles uit git komt, is "terug" geen herstel maar een nieuwe reconcile.

Wat dit vraagt is geen bijzondere techniek maar oefening: een failover die je nooit hebt uitgevoerd, bestaat niet. Daarom staat in de tabel per stadium wat je moet oefenen. In het lab is dat nu: herbouw op een leeg cluster — en dat is al gedaan.

Eerlijk over wat ontbreekt. Replicatie, promotie en DNS-failover zijn in dit lab niet gebouwd; ze zijn de volgende stap na de geheugenuitbreiding. Velero (back-up van clusterstaat en volumes) staat uit. Wat wél bewezen is: dat het cluster, het platform en de toepassingen uit git op te bouwen zijn, en dat ze dat in de goede volgorde doen.

soevereiniteit

Soevereiniteit: wat je in eigen hand houdt

"Soeverein" is geen locatie maar een lijst van dingen waarvan je zelf bepaalt wie ze heeft. In dit ontwerp:

haven

Wat Haven wél en niet garandeert

Wel: dat een Haven-compliant cluster de eigenschappen heeft die de vijftien checks toetsen — drie zones, drie control-plane-nodes, drie workers, hardening, privaat netwerk, actuele Kubernetes, RBAC, RWX-opslag, CNCF-conformance, automatische certificaten, logaggregatie, metrics. Een toepassing die op het ene Haven-cluster draait, draait op het andere.

Niet: dat de clusters elkaar kennen. Replicatie van data, verkeerssturing tussen locaties, identiteitsfederatie en back-up buiten de provider zijn jouw ontwerp bovenop Haven — en precies de dingen die in dit document boven de clusters getekend staan. Haven maakt ze mogelijk door de clusters gelijk te maken; het bouwt ze niet voor je.

Ook niet: kosten of prestaties. Een Haven-cluster bij een hyperscaler is duurder dan dezelfde capaciteit op eigen ijzer, en een Haven-cluster op één gaming-pc is goedkoper dan alles — maar valt om als de stroom uitvalt. De architectuur laat je kiezen; de keuze blijft van jou.