rig major updates
This commit is contained in:
118
rig/README.md
118
rig/README.md
@@ -100,24 +100,15 @@ ones you never type, or add whatever your own projects already say: each alias
|
||||
is two lines at the bottom of the file, calling the same script the canonical
|
||||
target does.
|
||||
|
||||
**`make tilt` works on a fresh copy, unedited.** rig ships `ctrl/Tiltfile`, and
|
||||
`k8s/base` already boots, so the dev loop comes up with the two examples running
|
||||
and nothing to configure first.
|
||||
**`make tilt` works on a fresh copy, unedited.** rig's `ctrl/Tiltfile` does
|
||||
rig's part — identity, context guard, registry, the manifests — and then includes
|
||||
the overlay's own Tiltfile. With no overlay named that is `examples/starter`, so
|
||||
the dev loop comes up with its two examples running and nothing to configure.
|
||||
|
||||
It hardcodes nothing. It asks `ctrl/ports.sh active` for this environment's
|
||||
cluster name, kube context, ports and manifest directory — the same values every
|
||||
other rig script resolves through `ctrl/lib/config.sh` — so a copied and renamed
|
||||
rig deploys into its own cluster with no edits. Every other project here writes
|
||||
its slug into the Tiltfile five or six times by hand, which is exactly the
|
||||
collision `kind-config.yaml.tpl` exists to avoid.
|
||||
|
||||
What it deploys is `MANIFESTS_DIR`, defaulting to rig's own `ctrl/k8s/overlays/dev`.
|
||||
Point that at an overlay versioned elsewhere and rig stops owning the manifests.
|
||||
|
||||
Replace the examples, then add your images and resources in the two marked
|
||||
sections. The catalogue below them holds the blocks that recur across every
|
||||
project here — `docker_build`, resource ordering, gateway reload, port-forwards —
|
||||
with the parts that are easy to get wrong already commented.
|
||||
cluster name, kube context, ports and paths — the same values every other rig
|
||||
script resolves through `ctrl/lib/config.sh` — so a copied and renamed rig, or a
|
||||
moved overlay, deploys into its own cluster with no edits.
|
||||
|
||||
`make help` lists every target.
|
||||
|
||||
@@ -126,81 +117,82 @@ nothing to download with — see [BOOTSTRAP.md](BOOTSTRAP.md), which runs the
|
||||
toolchain through the installer container and carries on to scaffolding and running
|
||||
a new project.
|
||||
|
||||
## One directory is one environment
|
||||
## What runs is an overlay
|
||||
|
||||
rig is the machine: toolchain, cluster, registry, port block, the dev loop's
|
||||
plumbing. What runs on it is an **overlay** — one folder, outside rig's version
|
||||
control, holding a use case: its settings (`rig.env`), its manifests
|
||||
(`k8s/overlays/dev`), its images and Tiltfile, its addons, its kind config if it
|
||||
needs its own. rig reads it and never writes into it. See
|
||||
[`docs/notes/overlay.md`](docs/notes/overlay.md).
|
||||
|
||||
```bash
|
||||
cp -r examples/starter local/myenv # local/ is gitignored
|
||||
OVERLAY=local/myenv make cluster up # or OVERLAY=local/myenv in ctrl/.env
|
||||
OVERLAY=local/myenv make tilt
|
||||
```
|
||||
|
||||
An overlay can also be a repo of its own, anywhere, or a project folder that
|
||||
carries rig at `<project>/rig/` with a three-line forwarding Makefile.
|
||||
|
||||
Copy this directory, rename it, run it. Cluster name, kubectl context, image
|
||||
tags and the host port block all derive from the directory name, so copies never
|
||||
collide and neither one's teardown can touch the other.
|
||||
## One environment per folder
|
||||
|
||||
A copy of this directory is a **sibling** of it, named after the environment it
|
||||
models (`acme-rig`). That is why the ignore rules for copies sit in the *parent*
|
||||
repo's `.gitignore` rather than here: a rule in this directory cannot see a
|
||||
directory beside it.
|
||||
Cluster name, kubectl context, image tags and the host port block all derive
|
||||
from a folder name — the overlay's when one is named, else rig's own — so copies
|
||||
never collide and neither one's teardown can touch the other. Two overlays run
|
||||
side by side from one rig; two copies of rig do too.
|
||||
|
||||
## Profiles
|
||||
|
||||
**rig needs no profile.** With none named it runs on built-in defaults: one node,
|
||||
no addons, a local registry, the newest Kubernetes version it pins. A profile is
|
||||
an optional overlay — a file in `ctrl/env.d/`, named by `PROFILE` — for when you
|
||||
want different addons or registry.
|
||||
|
||||
rig ships **examples**, not active profiles, because each one is a use case rather
|
||||
than something every rig needs. Copy one to use it:
|
||||
an optional file in `ctrl/env.d/`, named by `PROFILE`, that says how this machine
|
||||
reaches the world. rig ships two as **examples**; copy one to use it (the copy is
|
||||
gitignored):
|
||||
|
||||
| example | what it changes |
|
||||
| --- | --- |
|
||||
| `client.env.example` | images through a mirror of a corporate registry |
|
||||
| `mirror.env.example` | images through a pull-through cache of an internal registry |
|
||||
| `offline.env.example` | air-gapped: everything from a preloaded local registry |
|
||||
| `data.env.example` | databases and a scheduler: postgres, redis, airflow |
|
||||
|
||||
```bash
|
||||
cp ctrl/env.d/data.env.example ctrl/env.d/data.env
|
||||
PROFILE=data make cluster up # installs the profile's addons too
|
||||
PROFILE=data make check # what the profile wants, and what exists
|
||||
cp ctrl/env.d/mirror.env.example ctrl/env.d/mirror.env
|
||||
PROFILE=mirror make cluster up
|
||||
```
|
||||
|
||||
The **cluster itself** is one file, `ctrl/k8s/kind-config.yaml.tpl` (one node).
|
||||
To change it — more nodes, other port mappings — edit it and `make cluster
|
||||
reset`. The node count is read back out of it, so there is nothing to drift. The layout under `ctrl/k8s/` is the
|
||||
same as every other project here — a kind config, a kustomize `base/`, an
|
||||
`overlays/dev/` — see [`ctrl/k8s/README.md`](ctrl/k8s/README.md).
|
||||
The layers, weakest first: built-in defaults < `ctrl/versions.env` < the profile
|
||||
< the overlay's `rig.env` < `ctrl/.env` < your command line.
|
||||
|
||||
The **cluster itself** is one file: the overlay's `kind-config.yaml.tpl` if it has
|
||||
one, else rig's `ctrl/k8s/kind-config.yaml.tpl` (one node). To change it — more
|
||||
nodes, other port mappings, mounts — edit it and `make cluster reset`. The node
|
||||
count is read back out of it, so there is nothing to drift.
|
||||
|
||||
## Addons
|
||||
|
||||
Each addon is its own idempotent script in `ctrl/addons/`, and a profile names
|
||||
the ones it wants in `ADDONS`. Adding one is adding a file — there is no
|
||||
dispatcher to edit.
|
||||
Each addon is its own idempotent script, and `ADDONS` names the ones to install,
|
||||
in order. Adding one is adding a file — there is no dispatcher to edit. An
|
||||
overlay's `addons/<name>.sh` is found before rig's own.
|
||||
|
||||
**There is no ingress controller, deliberately.** They pin a narrow window of
|
||||
Kubernetes versions, so depending on one would constrain which k8s a rig can be
|
||||
built with — and running a trailing-edge control plane to model a legacy estate
|
||||
is the whole point. Services are reached through MetalLB and
|
||||
`type: LoadBalancer`, which carries no such constraint and is also what a real
|
||||
cluster does.
|
||||
built with — and running a trailing-edge control plane is often the point.
|
||||
Services are reached through MetalLB and `type: LoadBalancer`, which carries no
|
||||
such constraint and is also what a real cluster does.
|
||||
|
||||
rig's own addons make the cluster work:
|
||||
|
||||
| Addon | Does |
|
||||
| --- | --- |
|
||||
| `metallb` | gives `type: LoadBalancer` an address it can actually reach |
|
||||
| `cert-manager` | a local CA, so TLS works offline |
|
||||
| `metrics-server` | makes `kubectl top` work on kind |
|
||||
| `postgres` | database, in the `data` namespace |
|
||||
| `redis` | cache and broker |
|
||||
| `airflow` | scheduled pipelines; needs postgres and redis |
|
||||
|
||||
The last three are **cabinets**: a public service dropped in as-is, the upstream
|
||||
image unmodified, reachable at a known address. A cabinet is declared once and
|
||||
installs on either target — a `service.yml` composes it for a laptop, and these
|
||||
install the same one here. The names match on purpose: each cabinet carries a
|
||||
`rig_addon` field pointing at `ctrl/addons/<name>.sh`.
|
||||
|
||||
Plain manifests rather than helm charts, like every other addon: a chart repo is
|
||||
a network dependency, and the `offline` profile exists precisely so there is a
|
||||
path with none. Images are pinned in `ctrl/versions.env` and can be preloaded.
|
||||
|
||||
Passwords are generated on first install and kept across re-runs, so re-running
|
||||
an addon never rotates a credential out from under something already connected:
|
||||
What a workload needs — a database, a cache, a scheduler — belongs to its
|
||||
overlay. [`examples/data`](examples/data/) carries postgres, redis and airflow as
|
||||
plain manifests (no helm: a chart repo is a network dependency), with passwords
|
||||
generated on first install and kept across re-runs:
|
||||
|
||||
```bash
|
||||
kubectl -n data get secret postgres -o jsonpath='{.data.POSTGRES_PASSWORD}' | base64 -d
|
||||
kubectl -n data port-forward svc/airflow 8080:8080
|
||||
OVERLAY=examples/data make cluster up
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user