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>
107 lines
6.2 KiB
Markdown
107 lines
6.2 KiB
Markdown
# Guided bootstrap checklist
|
|
|
|
A single-page, ordered checklist covering the entire path from bare
|
|
machines to a working GitOps loop. It's meant to be worked through **with
|
|
Claude**, one item at a time — ask Claude to walk you through this list,
|
|
and it will run each step with you, wait for your output, confirm it
|
|
worked, and only then move to the next one. See `CLAUDE.md` at the repo
|
|
root for how Claude is primed to do this.
|
|
|
|
Each item names the doc it's drawn from, in case you want the full
|
|
explanation before or after running it. Replace `<NODE1_IP>`/`<NODE2_IP>`/`<NODE3_IP>`,
|
|
`<VIP_IP>`, `YOUR_GITHUB_USERNAME`, and the MetalLB IP addresses with your
|
|
real values throughout — Claude will remind you if you paste a command
|
|
still containing a placeholder, and will ask you for all of these directly
|
|
in Phases 2 and 5 rather than guessing them.
|
|
|
|
## Phase 1 — Prerequisites ([`01`](01-prerequisites.md))
|
|
|
|
- [ ] Three target machines chosen, each network-reachable, each with a
|
|
stable (ideally DHCP-reserved) IP address, each with a second disk
|
|
≥900GB set aside for Longhorn
|
|
- [ ] Custom Talos schematic built at factory.talos.dev with `iscsi-tools`
|
|
and `util-linux-tools`, ISO downloaded
|
|
- [ ] All three machines booted from that ISO, sitting at the boot screen
|
|
- [ ] `talosctl version --client` runs successfully
|
|
- [ ] `kubectl version --client` runs successfully
|
|
- [ ] `argocd version --client` runs successfully
|
|
- [ ] Repo forked on GitHub and cloned locally as **your own copy**
|
|
|
|
## Phase 2 — Talos bootstrap ([`02`](02-talos-bootstrap.md), [`talos/README.md`](../talos/README.md))
|
|
|
|
- [ ] **Ask Claude** to help pick: your three nodes' IP addresses (or
|
|
confirm DHCP reservations) and a separate VIP address — all based on
|
|
your actual LAN/DHCP setup
|
|
- [ ] `talosctl gen config gitops-starter https://<VIP_IP>:6443 --output-dir _out --config-patch-control-plane @talos/patch-controlplane.yaml --config-patch-control-plane @talos/patch-longhorn.yaml` run — `_out/controlplane.yaml`, `worker.yaml`, `talosconfig` exist
|
|
- [ ] `TALOSCONFIG` exported (or `talosctl config endpoint`/`node` set) to `_out/talosconfig`
|
|
- [ ] For **each** of the three nodes: `talosctl get disks --insecure --nodes <NODE_IP>` confirms two disks, then `talosctl apply-config --insecure --nodes <NODE_IP> --file _out/controlplane.yaml` run, node rebooted
|
|
- [ ] `talosctl bootstrap --nodes <NODE1_IP>` run — **exactly once**, against **exactly one** node
|
|
- [ ] `talosctl kubeconfig --nodes <VIP_IP> .` run, `KUBECONFIG` pointed at the result
|
|
- [ ] `kubectl get nodes` shows **all three** nodes, `Ready`
|
|
- [ ] `docs/network.md` updated with all three node addresses and the VIP
|
|
|
|
## Phase 3 — Argo CD install ([`03`](03-installing-argocd.md), [`argocd/README.md`](../argocd/README.md))
|
|
|
|
- [ ] `kubectl create namespace argocd`
|
|
- [ ] `kubectl apply --server-side -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml`
|
|
- [ ] `kubectl -n argocd wait --for=condition=Available --timeout=300s deployment --all` completes
|
|
- [ ] Initial admin password retrieved
|
|
- [ ] `kubectl -n argocd port-forward svc/argocd-server 8080:443` running in its own terminal
|
|
- [ ] `argocd login localhost:8080 --username admin --password <pw> --insecure` succeeds
|
|
|
|
## Phase 4 — Hand the cluster to Git ([`04`](04-app-of-apps.md))
|
|
|
|
- [ ] `spec.source.repoURL` fixed in all four placeholder files: run
|
|
`grep -rl YOUR_GITHUB_USERNAME .` to find them
|
|
(`argocd/app-of-apps/app-of-apps.yaml`, `apps/demo.yaml`,
|
|
`apps/metallb.yaml`, `apps/longhorn.yaml`)
|
|
- [ ] Edit committed and pushed to your fork's `main` branch
|
|
- [ ] `kubectl apply -f argocd/app-of-apps/app-of-apps.yaml`
|
|
- [ ] `argocd app list` shows `app-of-apps`, `Synced`/`Healthy`
|
|
- [ ] `argocd app list` shows `demo`, `metallb`, and `longhorn`, appeared
|
|
automatically, all `Synced`/`Healthy`
|
|
- [ ] `kubectl -n demo get pods,svc` shows the demo app's Pod running
|
|
(Service `EXTERNAL-IP` still `<pending>` — expected for now)
|
|
|
|
## Phase 5 — MetalLB: real IP addresses ([`05`](05-metallb.md))
|
|
|
|
- [ ] **Ask Claude** to help pick: a MetalLB pool range, an address for
|
|
Argo CD's UI, and an address for the demo app — all based on your
|
|
actual LAN/DHCP setup
|
|
- [ ] `apps/metallb/templates/ipaddresspool.yaml` edited to your real pool range
|
|
- [ ] `apps/demo/service.yaml` edited to your real demo app address
|
|
- [ ] `docs/network.md` updated with the pool range and both addresses (Argo CD's added once patched, below)
|
|
- [ ] Committed, pushed, and synced (`argocd app sync metallb demo`)
|
|
- [ ] `kubectl -n demo get svc demo` shows a real `EXTERNAL-IP`; page loads at `http://<that-address>`
|
|
- [ ] `argocd-server` Service patched to `LoadBalancer` with your chosen Argo CD address (`kubectl -n argocd patch svc argocd-server ...`)
|
|
- [ ] Argo CD UI reachable at `https://<that-address>` with no port-forward running
|
|
|
|
## Phase 6 — Longhorn: real storage ([`06`](06-longhorn.md))
|
|
|
|
- [ ] `kubectl -n longhorn-system get pods` shows manager/CSI Pods
|
|
`Running` on all three nodes
|
|
- [ ] `kubectl get storageclass` shows a default `longhorn` StorageClass
|
|
- [ ] (Optional) Gave the demo app a real PVC and confirmed it's `Bound`
|
|
with a healthy, replicated Longhorn volume behind it
|
|
|
|
## Phase 7 — Prove the loop ([`07`](07-your-first-change.md))
|
|
|
|
- [ ] Edited the `<h1>` text in `apps/demo/configmap.yaml`
|
|
- [ ] Committed and pushed
|
|
- [ ] `argocd app sync demo` (or waited for auto-poll) shows the change applied
|
|
- [ ] Refreshed the browser — new text visible
|
|
- [ ] (Optional) Triggered self-heal: hand-edited the ConfigMap with `kubectl patch`, confirmed Argo CD reverted it
|
|
|
|
## You're done when
|
|
|
|
Every box above is checked, you've watched a change you made in a text
|
|
editor show up in a browser without ever running `kubectl apply` yourself
|
|
for it, and you can explain in your own words what happened between "git
|
|
push" and the page updating. If you can't yet, that's the sign to ask
|
|
Claude for a walkthrough of whichever phase felt shaky before calling this
|
|
finished.
|
|
|
|
From here: [`08-adding-new-apps.md`](08-adding-new-apps.md) to add
|
|
something of your own, or [`09-growing-up.md`](09-growing-up.md) for the
|
|
bigger next steps (more nodes, ingress, secrets management).
|