Move to a three-node cluster with a Talos VIP; add Longhorn

Every node is now both control plane and worker, giving real tolerance
for losing any single machine (etcd quorum needs 3, not 1). A Talos VIP
gives the cluster one stable address regardless of which node answers.

Also pre-installs Longhorn for replicated storage, backed by a Talos
UserVolume on each node's second disk (>=900GB, non-system) rather than
the default path — mirroring the pattern from the homescale repo.

Docs renumbered to make room for 06-longhorn.md; checklist, glossary,
network map, and CLAUDE.md's guided-bootstrap instructions updated to
match, including asking the user for node IPs, VIP, and disk info before
generating any Talos config.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Maxwell Morris
2026-08-22 18:25:38 +01:00
co-authored by Claude Sonnet 5
parent 92c3ad3191
commit 110bd97cca
26 changed files with 777 additions and 261 deletions
+17 -3
View File
@@ -13,6 +13,21 @@ assigned or changed, so you (or Claude) never have to reverse-engineer
> instruction that tells Claude to do this on its own when it makes such a
> change itself.
## The three nodes and the VIP
None of these are from the MetalLB pool below — they're the machines
themselves and the shared address Talos elects between them. Set in
[`talos/README.md`](../talos/README.md); see
[`docs/02-talos-bootstrap.md`](02-talos-bootstrap.md) for what the VIP is
and why it's separate from any one node's address.
| Address | What | Port | URL |
|---|---|---|---|
| `EDIT ME` | Node 1 | 6443 | `https://EDIT ME:6443` |
| `EDIT ME` | Node 2 | 6443 | `https://EDIT ME:6443` |
| `EDIT ME` | Node 3 | 6443 | `https://EDIT ME:6443` |
| `EDIT ME` | Cluster VIP (use this one, not a node's own address) | 6443 | `https://EDIT ME:6443` |
## MetalLB pool
| | |
@@ -20,16 +35,15 @@ assigned or changed, so you (or Claude) never have to reverse-engineer
| Range | `EDIT ME — e.g. 192.168.1.240-192.168.1.250` |
| Configured in | [`apps/metallb/templates/ipaddresspool.yaml`](../apps/metallb/templates/ipaddresspool.yaml) |
## Allocated addresses
## Allocated addresses (from the MetalLB pool)
| Address | What | Namespace | Port(s) | URL | Source |
|---|---|---|---|---|---|
| `<NODE_IP>` | Talos node — Kubernetes API server | — | 6443 | `https://<NODE_IP>:6443` | Not from the MetalLB pool — the node's own address, set in [`talos/README.md`](../talos/README.md) |
| `EDIT ME` | Argo CD UI/API (`argocd-server`) | `argocd` | 443 | `https://EDIT ME` | Patched to `LoadBalancer` by hand — see [`docs/05-metallb.md`](05-metallb.md) |
| `EDIT ME` | Demo app | `demo` | 80 | `http://EDIT ME` | [`apps/demo/service.yaml`](../apps/demo/service.yaml) |
Add a row here every time you add a new app with a `LoadBalancer` Service
(see [`docs/07-adding-new-apps.md`](07-adding-new-apps.md)). Leave the URL
(see [`docs/08-adding-new-apps.md`](08-adding-new-apps.md)). Leave the URL
column's port number off only when it's the protocol default (80 for
`http://`, 443 for `https://`) — include it otherwise.