Text-only cleanup after the upgrade campaign. Updates stale version strings, prose, and comments to the verified current facts; no Kubernetes behavior or version pins changed except the kubectl toolchain bump (below). Verified facts applied: k3s v1.36.4+k3s1, Debian 13 trixie, Cilium 1.20.1 / Gateway API v1.6.1, Longhorn 1.12.1, node RAM 24 GiB, dedicated virtio2 SSD etcd disk per node, Velero chart 12.x / v1.18, Grafana 13.2.0. - Version strings across infra/ and platform/ READMEs + comments - kubectl toolchain 1.31.4 -> 1.36.4 (devcontainer/ci/conformance versions.env; 1.31 vs a 1.36 cluster exceeded the +-1 skew) - Retired-single-apps-Kustomization refs -> apps-wave-0/1/2 + apps-vms with per-wave SOPS decryption (flux/clusters docs + bootstrap.sh) - COMPLETED/historical banners on the three executed plan docs - Resolved TODO(WS-SEC) markers -> Renovate-maintained ranges - Appended dated DECISIONS-LOG entry (2026-08-30) superseding the 2026-08-26 LIVE STATE line Left as revalidation items (not blind-edited): external-snapshotter v8.2.0 vs 1.36, Cilium ext_authz/forward-auth relevance under 1.20.1, conformance ImageVolume feature-gate assertions under 1.36. Co-Authored-By: Claude Opus 4.8 <[email protected]>
92 lines
4.4 KiB
Markdown
92 lines
4.4 KiB
Markdown
# clusters/
|
|
|
|
Flux entrypoints and the environment-overlay model (**R-ENV-02**, **R-GITOPS-01/02/03**).
|
|
|
|
Governing spec: [`docs/05-gitops-and-delivery.md`](../../home-network-k3s/docs/05-gitops-and-delivery.md),
|
|
[`docs/02-environments-and-provisioning.md`](../../home-network-k3s/docs/02-environments-and-provisioning.md),
|
|
[ADR-0004 (Flux)](../../home-network-k3s/decisions/adr-0004-gitops-flux.md).
|
|
|
|
> Phase 0 scaffolding only. These are structurally-correct stubs. **No cluster exists** — nothing
|
|
> here reconciles until WS-INFRA delivers a cluster and bootstraps Flux (roadmap Phase 1).
|
|
|
|
## Layout — base + overlay (never fork the base)
|
|
|
|
```
|
|
clusters/
|
|
base/ shared Flux objects (one authoring, both environments)
|
|
flux-system.yaml GitRepository — the reconciliation source (bootstrap → Gitea)
|
|
platform.yaml Flux Kustomization → ./platform (reconciles first)
|
|
apps-wave-0.yaml Flux Kustomization → ./apps/wave-0 (dependsOn platform-config)
|
|
apps-wave-1.yaml Flux Kustomization → ./apps/wave-1 (dependsOn apps-wave-0)
|
|
apps-wave-2.yaml Flux Kustomization → ./apps/wave-N (dependsOn apps-wave-N-1)
|
|
cluster-vars.yaml ConfigMap of overlay knobs (BASE defaults)
|
|
kustomization.yaml
|
|
dev/ ACTIVE build target — patches cluster-vars with dev values only
|
|
kustomization.yaml
|
|
prod/ DESIGN-ONLY until roadmap Phase 7 — patches cluster-vars with prod values only
|
|
kustomization.yaml
|
|
```
|
|
|
|
## How the overlay model satisfies R-ENV-02
|
|
|
|
The base authors the reconciliation graph **once**. `platform.yaml` and the app-wave Kustomizations
|
|
(`apps-wave-0/1/2.yaml` — the single `apps.yaml` was retired; `apps-vms.yaml` deliberately omits it,
|
|
see below) declare `postBuild.substituteFrom` the `cluster-vars` ConfigMap. Platform and
|
|
app manifests use `${TOKEN}` placeholders for every value that legitimately differs between
|
|
environments (issuer, replica counts, storage sizes, retention, node placement).
|
|
|
|
**`clusters/dev` and `clusters/prod` differ ONLY by the values they patch into `cluster-vars`** —
|
|
they add no resources of their own and never copy/fork a base manifest. Promotion to prod
|
|
([`docs/02`](../../home-network-k3s/docs/02-environments-and-provisioning.md)) is a change to the
|
|
prod overlay's variables, nothing else.
|
|
|
|
## How Flux is pointed at an environment
|
|
|
|
`flux bootstrap` (run by WS-INFRA in Phase 1) targets one environment's path per cluster:
|
|
|
|
```
|
|
# dev cluster
|
|
flux bootstrap ... --path=clusters/dev
|
|
# prod cluster (Phase 7 only — design-only until then)
|
|
flux bootstrap ... --path=clusters/prod
|
|
```
|
|
|
|
Bootstrap materializes the `flux-system` `Kustomization` that renders the chosen overlay, which pulls
|
|
in `base/` and applies the env-scoped `cluster-vars`.
|
|
|
|
## Reconciliation order
|
|
|
|
```
|
|
GitRepository (flux-system)
|
|
│
|
|
▼
|
|
Kustomization: platform (./platform, substituteFrom cluster-vars)
|
|
│ healthy
|
|
▼
|
|
Kustomization: apps-wave-0 (./apps/wave-0, dependsOn platform-config, substituteFrom cluster-vars)
|
|
│ healthy
|
|
▼
|
|
Kustomization: apps-wave-1 (./apps/wave-1, dependsOn apps-wave-0)
|
|
│ healthy
|
|
▼
|
|
Kustomization: apps-wave-N (./apps/wave-N, dependsOn apps-wave-N-1)
|
|
```
|
|
|
|
Wave 0 `dependsOn` `platform-config` (transitively `platform`) so CNI/storage/TLS/DNS/gateway
|
|
exist before any workload reconciles. The app tier is split into dependency-ordered WAVES
|
|
(`catalog/render.py --emit-waves`): each `apps-wave-<N>` health-gates (wait:true) ONLY its own
|
|
wave, so a crashloop in a later wave can no longer stall an earlier wave or block new revisions.
|
|
See [DESIGN-waves.md](../DESIGN-waves.md) for the wave table + cutover runbook.
|
|
|
|
## TODOs (later phases — do not action in Phase 0)
|
|
|
|
- **Source cutover (WS-GITOPS, Phase 6):** `base/flux-system.yaml` currently points at the bootstrap
|
|
source. After Gitea is onboarded, repoint `spec.url` to `gitea.home.keithjackson.dev` and keep an
|
|
off-cluster mirror (spec `docs/05` "Source-of-truth", `CONTRIBUTING.md`).
|
|
- **SOPS decryption (WS-SEC, Phase 1):** add `spec.decryption.provider: sops` (age secret name only,
|
|
never plaintext) to the platform/apps Kustomizations once the age key is bootstrapped
|
|
([ADR-0007](../../home-network-k3s/decisions/adr-0007-secrets-sops-age.md)).
|
|
- **Split ordered Flux Kustomizations** if intra-platform ordering needs to be explicit (e.g. a
|
|
separate `cilium`/`longhorn` Kustomization others `dependsOn`).
|
|
</content>
|