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>
6.3 KiB
02 — Bootstrapping Talos
At the end of this doc, you'll have a three-node Kubernetes cluster, running nothing but Kubernetes itself (plus the storage prep Longhorn needs later). No Argo CD yet — that's next.
Why Talos, specifically
Most guides have you install a general-purpose Linux distribution, then
install Kubernetes on top by hand or with a tool like kubeadm — meaning
there's a whole normal OS underneath, with a package manager, an SSH
daemon, and every other thing that can drift out of a known-good state or
need patching. Talos throws that away: it's an OS whose only job is running
Kubernetes. There's no SSH, no shell to log into, no packages to manage —
you configure it entirely by sending it a machine config file over the
network (the talosctl commands below), and it applies that config the
same declarative way Kubernetes applies your app manifests. Less surface
area, less to secure, less to keep in sync by hand — the same philosophy as
the rest of this stack, one layer lower.
Three nodes, each both control plane and worker
A "real" Kubernetes cluster has multiple nodes — some running the control plane (the brain: API server, scheduler, the cluster's own database, called etcd) and others as workers (running your actual apps) — so that losing one machine doesn't take the whole cluster down. This repo starts with three nodes, each acting as both control plane and worker, which gets you real resilience — survive losing any one machine — without needing more than three.
Why three specifically, and not two: etcd (the control plane's database)
uses quorum — a majority vote among its members — to agree on cluster
state, and a majority only means something with an odd number of voters.
With one control-plane node, losing it loses the cluster outright. Two
doesn't help: losing either one leaves one survivor, which is not a
majority of two. Three is the smallest number where losing any one
still leaves two — a majority — able to keep agreeing on state. This is
also why docs/09-growing-up.md — once you're past
this doc — specifically warns against going to four control-plane nodes
later: four doesn't improve on three's fault tolerance, it just makes
quorum math worse.
The VIP: one address for a cluster that moves
With three control-plane nodes, "where's the API server?" no longer has
one fixed answer — it's whichever nodes happen to be up right now. Talos's
VIP (Virtual IP) feature solves this: the three nodes continuously
elect one of themselves to answer on one shared IP address you choose, and
re-elect within seconds if that node goes down. Everything that talks to
this cluster — talosctl, kubectl, the Application manifests in this
repo — points at the VIP, never at one node's own address. See the
vip block in
talos/patch-controlplane.yaml.
Ask Claude: "help me pick the VIP address for my cluster" before you generate any config — same kind of decision as the MetalLB pool in
docs/05-metallb.md: a real, unused address on your LAN, outside your DHCP range, that Claude can't guess on its own.
Preparing storage for Longhorn
Each node also gets a second disk reserved for
Longhorn, this repo's pre-installed storage layer —
handled by talos/patch-longhorn.yaml,
applied at the same time as the control-plane patch below. Read that
file's comments; the short version is that Talos finds, formats, and
mounts a disk for Longhorn on its own, using rules you set (not the system
disk, at least 900GB), so there's no manual partitioning step here.
Steps
Full exact commands live in talos/README.md — read
that alongside this doc; this section explains what's happening at each
stage, that one has copy-paste blocks. You'll repeat most of these steps
three times, once per node — talosctl README.md calls out exactly
which commands are "once" vs. "once per node."
-
Generate machine configuration.
talosctl gen configproduces Talos's config files for your cluster, with bothtalos/patch-controlplane.yaml(scheduling + the VIP) andtalos/patch-longhorn.yaml(storage prep) baked in — read both files, they explain themselves. This produces onecontrolplane.yaml, applied identically to all three nodes; there's no separate worker config in this setup, since every node is both. -
Apply the config to each node. Each node, freshly booted from your custom Talos ISO, is sitting in "maintenance mode" with no configuration.
talosctl apply-configsends it the config from step 1. Run this once per node, pointed at that node's own address. Each node reboots, installs Talos to its system disk, formats and mounts its second disk for Longhorn, and comes up running for real. -
Bootstrap etcd.
talosctl bootstrapinitializes the cluster's data store. This is a one-time, one-node-ever operation, run against exactly one of your three nodes — even though all three will end up running etcd, only one of them needs telling to start the cluster; the other two join the existing one once it exists. -
Retrieve your kubeconfig.
talosctl kubeconfigdownloads the credentials you'll use to talk to Kubernetes withkubectl— the Kubernetes equivalent of thetalosconfigyou got in step 1. Point it at the VIP, not at any one node. -
Verify.
kubectl get nodesshould show all three nodes,Ready.
Ask Claude: "what's the difference between a kubeconfig and a talosconfig, and why are they separate files?" is a good one to ask once you've got both — the split trips people up the first time.
Checklist
- VIP address chosen, with Claude's help, for your LAN
_out/controlplane.yamlandtalosconfiggenerated, with both patches applied- Config applied to all three nodes; each has rebooted, installed Talos, and mounted its Longhorn disk
talosctl bootstraprun exactly once, against exactly one node- kubeconfig retrieved, pointed at the VIP
kubectl get nodesshows all three nodesReady
Once all three nodes are Ready, continue to
docs/03-installing-argocd.md.