Read the cluster the way a packet does.
This material is organised along the request path rather than by object type, because nearly every unusual choice in the pl-waw cluster traces back to one constraint. Violet marks a choice that traces back to it.
Track one
The request path
One HTTPS request, from a browser to a tenant’s code.
The A record
Where a normal cluster puts a load balancer’s address, this one puts the worker node’s.
no LB 2q hop 2The node’s :80 and :443
Traefik is a DaemonSet holding the node’s ports directly. It has no Service at all.
no LB 3q hop 3TLS, by HTTP-01 only
One ClusterIssuer, one challenge type, and therefore no wildcard certificates anywhere.
no LB 2q hop 4Matching the request
Traefik v3 routers, both providers on, and one setting that is off by default for good reason.
1q hop 5Service, and what it actually does here
The Service names the backend. For CRD-routed traffic it is not in the data path at all.
1q hop 6The pod, inside gVisor
One node means tenant code and platform code share a kernel. gVisor is what stands between them.
no LB 2q hop 7The data path, shared
Roughly 100 tenant databases per Postgres cluster, 500 per ClickHouse. One node makes that the only option.
no LB 2qTrack two
The change path
One push, from a tenant’s git to a running pod.
Forgejo, on :2222 and through the API
Git over SSH on a node port, git over HTTPS through Traefik — where a correct HTTP default breaks git.
no LB 2q hop 9BuildKit, rootless and tokenless
A Dockerfile is a program a tenant wrote. The Job is built so that running it grants nothing.
2q hop 10Kustomize apply, with no reconciler
One directory per app, digest-pinned images, and nothing running in the background to keep the cluster equal to the repo.
errata 1qThe most classroom time
Three files, read line by line
The pieces worth the most time, each with its annotations pinned to the lines that carry the reason.
platform/traefik/values.yaml
The hostPort model
The file where "no cloud load balancer" stops being a decision and becomes a configuration. Six of its settings are unusual, and every one of them is unusual for the same reason.
25 min of classroom time · 10 annotationsapps/deployer/rbac.yaml
Write-only RBAC
Secrets are create and patch, never get or list. The deployer can install a credential it cannot read back — and the reason that works at all is a detail about which verb you choose.
documentation/external-clusters.md
The edge/workload split
pl-waw is the edge and holds every public certificate; workload clusters hold none and are reachable only over mTLS. The seam is an ExternalName Service plus a ServersTransport.
25 min of classroom time · 7 annotationsBefore this ships
Two findings, left in on purpose
Both were found while reading the repo and neither is fixed in the manifests. One breaks a documented bootstrap step; the other is the better teaching example.
infrastructure/apps/kustomization.yaml
Two apps are in the tree and in no kustomization
infrastructure/apps/kustomization.yaml lists eight apps under resources:. The repository contains ten. deployer/ and mail-in/ are absent from the list.
infrastructure/README.md
The README’s layout section predates four directories
The layout section in infrastructure/README.md was written before batteries/, deployer/, docs/ and enterprise/ existed. It documents the tree as it was, and nothing has updated it since.