Update Longhorn docs for two-worker topology

This commit is contained in:
2026-09-03 03:28:13 +01:00
parent 9bb29eee5a
commit 39e04e43d0
+44 -20
View File
@@ -18,11 +18,21 @@ metal — your three Talos nodes — nothing provides that on its own, the
same gap MetalLB fills for IP addresses rather than storage. same gap MetalLB fills for IP addresses rather than storage.
**Longhorn** is that provider: it turns a plain disk on each node into one **Longhorn** is that provider: it turns a plain disk on each node into one
pool of storage, and — because your cluster has three nodes — it pool of storage, and replicates each volume across more than one node. Lose
replicates each volume across more than one of them. Lose a node, and the a node, and the data backing any volume that had a replica elsewhere is
data backing any volume that had a replica elsewhere is still there. This still there. This is why Longhorn needs more than one storage-providing
is also why Longhorn is genuinely a **three-node** story: with one node, node at all: with only one, "replicated storage" has nothing to replicate
"replicated storage" has nothing to replicate *to*. *to*.
This cluster deliberately keeps storage off the three Raspberry Pi control
planes — they have no data disk and are not meant to run application
workloads (see [`docs/02-talos-bootstrap.md`](02-talos-bootstrap.md)).
Longhorn instead runs only on the two dedicated Proxmox workers, each with
its own local NVMe-backed disk on a separate physical host (Gimli and
Titus). `defaultReplicaCount: 2` in
[`apps/longhorn/values.yaml`](../apps/longhorn/values.yaml) matches that:
with exactly two storage nodes, two replicas is the most redundancy
possible — losing either worker still leaves one complete copy.
## What's already running ## What's already running
@@ -33,23 +43,35 @@ umbrella-chart pattern as MetalLB, just without any extra templates of its
own this time. own this time.
The interesting configuration already happened at the Talos layer, back in The interesting configuration already happened at the Talos layer, back in
[`talos/patch-longhorn.yaml`](../talos/patch-longhorn.yaml): each node [`talos/patch-longhorn.yaml`](../talos/patch-longhorn.yaml): each worker
found, formatted, and mounted its own ≥900GB disk at found, formatted, and mounted its own ≥300GiB disk at `/var/mnt/longhorn`.
`/var/mnt/longhorn`. [`apps/longhorn/values.yaml`](../apps/longhorn/values.yaml) [`apps/longhorn/values.yaml`](../apps/longhorn/values.yaml) points Longhorn's
points Longhorn's `defaultDataPath` at that exact path — this is the thing `defaultDataPath` at that exact path — this is the thing that makes Longhorn
that makes Longhorn use *that* disk instead of carving space out of each use *that* disk instead of carving space out of each node's root filesystem
node's root filesystem (small, and on Talos, not meant for this kind of (small, and on Talos, not meant for this kind of data anyway).
data anyway). [`talos/patch-worker.yaml`](../talos/patch-worker.yaml) also labels each
worker `node.longhorn.io/create-default-disk=true`, which is what actually
limits default-disk creation to these two nodes instead of every node in
the cluster — without it, Longhorn would try (and fail) to create a
default disk on the Raspberry Pi control planes too.
## Verify it's actually working ## Verify it's actually working
```sh ```sh
kubectl -n longhorn-system get pods kubectl -n longhorn-system get pods -o wide
``` ```
Expect a `longhorn-manager` and `longhorn-csi-plugin` Pod on each of your Expect a `longhorn-manager` and `longhorn-csi-plugin` Pod on each of the
three nodes, plus one `instance-manager` per node once a volume exists, two workers (not the control planes), plus one `instance-manager` per
all `Running`. worker once a volume exists, all `Running`. Confirm Longhorn agrees which
nodes are eligible storage nodes:
```sh
kubectl -n longhorn-system get nodes.longhorn.io -o wide
```
Only the two workers should show `READY=true`, `ALLOWSCHEDULING=true`,
`SCHEDULABLE=true`.
```sh ```sh
kubectl get storageclass kubectl get storageclass
@@ -86,13 +108,15 @@ once the pre-installed pieces are confirmed working, not a requirement to
move on. move on.
> **Ask Claude:** "what would happen to that PVC's data if I lost one of > **Ask Claude:** "what would happen to that PVC's data if I lost one of
> my three nodes right now?" — worth being able to answer before you trust > my two storage workers right now?" — worth being able to answer before you
> this with anything real. > trust this with anything real.
## Checklist ## Checklist
- [ ] `kubectl -n longhorn-system get pods` shows manager/CSI Pods - [ ] `kubectl -n longhorn-system get pods -o wide` shows manager/CSI Pods
`Running` on all three nodes `Running` on both workers, and none on the control planes
- [ ] `kubectl -n longhorn-system get nodes.longhorn.io` shows exactly the
two workers as schedulable storage nodes
- [ ] `kubectl get storageclass` shows a default `longhorn` StorageClass - [ ] `kubectl get storageclass` shows a default `longhorn` StorageClass
- [ ] (Optional) Gave the demo app a real PVC and confirmed it's `Bound` - [ ] (Optional) Gave the demo app a real PVC and confirmed it's `Bound`
with a healthy, replicated Longhorn volume behind it with a healthy, replicated Longhorn volume behind it