ctrl/k8s — the cluster, and what runs on it
Same layout as every other project here: a kind config, a kustomize base/,
and an overlays/dev/ that patches it.
kind-config.yaml.tpl the cluster itself — nodes, ports
base/ the components, as plain manifests
overlays/dev/ how this rig differs from the base
Why the cluster config is a template
Every other project checks in a literal kind-config.yaml, because there is
exactly one unt and one nvi. A rig is copied and renamed to make a second
environment, and both the cluster name and the host port block follow the
directory name — so a literal would make every copy collide on both.
ctrl/cluster.sh renders it with sed, substituting ${CLUSTER},
${NODE_IMAGE}, ${HTTP_PORT} and ${HOST_WORKDIR}. Not envsubst: that is
gettext-base, which a minimal Debian does not have, and Docker being the only
prerequisite is the one promise rig makes.
To change the cluster, edit this file — more nodes, other port mappings —
then make cluster reset: a kind config is fixed at creation, not re-applied.
lib/config.sh reads the node count back out of it, so nothing restates it.
A project that builds its own cluster through rig passes its own file as
KIND_CONFIG=<path>; it is rendered the same way.
base/ — replace these
The two components in base/ are examples, not the system. They exist so
the real manifests have a shape to be written against.
The real ones are expected to be versioned separately from the installer —
they change on a different cadence, by different people, under different review.
Point MANIFESTS_DIR in ctrl/.env at their overlay and rig stops owning them:
MANIFESTS_DIR=../platform-manifests/overlays/dev
Until then it defaults to ctrl/k8s/overlays/dev.
The three states a component can be in
Switching between them should be a one-line change, never a rewrite. The DNS name stays the same in every case, so callers never know the difference:
| state | what exists | when |
|---|---|---|
| real | an image built from source, hot-reloaded | the one thing you are working on |
| mock | a stub returning canned responses (example-mock.yaml) |
everything else — most of the estate |
| remote | no pod at all, just a Service (example-remote.yaml) |
when the real system is reachable and you want it |
Most components should be mock. What has to be faithful is the topology — names, ports, dependency order, who can reach whom, how it fails. The workloads are noise, and mocking them is what makes several copies of a large estate fit on one laptop.