feat(repartition): give the whole disk tail to ZFS, one worker at a time #2159
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/pipeline-repartition-node"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Mayastor was removed on 2026-09-04. Its 288.8G partition is still carved on every 457.8G worker and now holds nothing, while
tankruns on 143G at 57-78% full and 55-66% fragmented — one node wouldn't accept a new 1Gi volume at all. Abootc switchroll can't fix this: it reboots with the disk intact and cannot rewrite a partition table.Requires
sean/seanfarm#250 to land and converge first.kernel-deploy-guardisfailurePolicy: Fail, so an unlisted creator is denied at the preflight agent — before anything is cordoned.Why the work runs at early boot
Forced, not stylistic:
k3s-agent.serviceis bakedKillMode=processwith nok3s-killall.sh, so stopping it leaves containerd and every shim alive holding ZFS mounts.tank/containerd, so a livezpool destroy tankwould unmount the filesystem its payload executes from.So the agent arms a one-shot systemd unit ordered before the ZFS import units, and reboots. With
bimageset it alsobootc switches in the same visit — one reboot per node, not two.The containerd trap
A hand-run repartition of
seanfarm-worker-2a9194earlier today succeeded at the disk level and left the node unable to start any container:containerd's metadata database lives on
sda3and survives the pool it indexes. Afterzpool destroyit still listed ~200 snapshots with no datasets, so every unpack failed — and the node couldn't run the pod that would have repaired it. Recovery needed out-of-band SSH. The boot script now clears that metadata in the same unit, beforek3s-agentever starts.Ordering that isn't obvious
Uncordon comes before the reclaim, deliberately inverting
k3s-remove-node.sh, which cleans while cordoned because its node is leaving. Here the node is returning and every volume must come back to it: MinIO ismaxSkew:1+DoNotScheduleand all three ZFS classes areWaitForFirstConsumer, so the just-emptied node is the only domain that can take the replacement. Cleaning while cordoned scatters them and leaves two erasure drives or two Postgres instances sharing a host.The reclaim deletes PVC, PV and ZFSVolume.
k3s-remove-node.shdeleted only the PVC — which is why 14 orphaned ZFSVolume CRs had accumulated, the finalizer never clearing once the owner node is gone.The gate
The four Mayastor predicates removed in v0.1.743 were the gate's only truthful storage checks. Pod liveness is fine for a reboot, where data survives, and not for an operation that destroys it. Added: MinIO online/healing drive counts from the unauthenticated cluster metrics, per-ordinal OpenBao
/v1/sys/health(200 == initialized and unsealed and active-or-standby), and a no-PVC-Pending predicate that catches an incomplete reclaim. Fail-closed throughout.greenBudgetdefaults 5400, not 2400 — a CNPG re-clone alone measured 57m35s for three instances.Safety
dryRundefaults true, inverted from the kernel roll. Shares thekernel-deploymutex, holdskernel-deploy-nodeacross the whole node including its green gate, and pins orchestrator pods to the control plane so the workflow can never drain the node it runs on.The dedicated SA can delete a dead PV/PVC/ZFSVolume and cannot create or patch one;
nodes: patch, neverdelete.Verified by mutation
tests/repartition-safety-envelope.shpins the orderings by line number. Each of these turns it red:the boot script does not clear containerd metadatalabelclearaftersgdisk -dlabelclear must precede sgdisk -d (labelclear=285 delete=283)arm the intent file AFTER enabling the unitnodes: deletea repartition must never delete a nodebash tests/check.sh— 147/147 guards pass.https://claude.ai/code/session_01MdSbMhzabSbpG8TtP9Ur3H