This repository is now the public half of a split: six documents saying what to decide, and one gap. How the cluster is built moved to jeffry/homelab-impl, which is private because its README is an inventory of chart versions and image tags. History starts here deliberately, and not as tidiness. The previous history contained that inventory, and this repository is public — a deletion commit would have removed it from the tree and left it in the log. A fresh root can only carry what is in it. Two pointers rewritten rather than deleted: private-access.md and .loom/README.md both directed a reader to TAILSCALE.md and README.md at the root, which are now private. They now say a fuller reference exists, that it is private, and how to ask — because a public page naming a private thing as its answer is the failure this project has now hit four times. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1.8 KiB
What a volume here can and cannot do
local-path is the only StorageClass and it is the default. Everything
below follows from that, and none of it is negotiable without adding replicated
storage, which is not deployed.
A volume belongs to one machine, permanently
Every volume carries a hard affinity to the node backing it. So anything with a volume inherits the availability of one machine, and the only variable left is which one.
Anything that assumes it can be rescheduled freely is assuming something this cluster does not provide.
Choose the node deliberately rather than letting it land. A volume that lands somewhere by accident becomes a single point of failure nobody picked — which happened once, and the service could not come back when that node died.
A volume cannot be grown
ALLOWVOLUMEEXPANSION is false. Growing one means dump and restore, or
manual migration — not an edit.
Size with headroom. This is the constraint most likely to be discovered late.
Where this does not bite
Postgres run by the operator is shared-nothing and replicates at the database level, so a cluster of two survives losing a node even though neither volume can move. The node affinity is intended there rather than tolerated. See databases.
What would change this
Replicated storage — Longhorn being the obvious candidate — is deliberately not deployed. A substantial thing to operate on three nodes, and the downtime has not yet cost anything. Revisit when it does.
Checking this is still true
Verified 2026-09-03.
kubectl get sc # local-path, default, ALLOWVOLUMEEXPANSION false
kubectl get pvc -A
kubectl get pv -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeAffinity