Disk failures, node rebuilds, and verification¶
A failing disk is not a failing node. Since v0.3 the global DRBD
config defaults to on-io-error detach (drbd.onIoError): a leg
whose backing device errors drops to Diskless and the volume keeps
serving through the peer instead of surfacing I/O errors into the pod. The
detached leg shows as DiskState: Diskless in
kubectl describe miroirvolume and miroir_volume_disk_failed goes
1 for that node: replace the disk, then remove and re-add the
replica.
Rebuilding a node is safe. A reinstall (e.g. Talos wipe) destroys
the backing devices and miroir's node-local state together; when the
node rejoins, the agent detects the wipe and makes each recreated leg
a full sync target rather than trusting its empty disk. Full syncs
stay thin automatically: instead of literally writing every zero
byte of unused space (which would balloon a thin-provisioned pool to
the volume's full virtual size), the agent probes each lvmthin/zfs
backing device's discard granularity and configures DRBD to send
runs of zeros as discards — the same "these blocks are free" signal
fstrim uses — so a re-synced leg consumes only what the data needs
(loopfile legs are skipped, loop devices mishandle it;
drbd.resync.discardGranularity remains as a manual cluster-wide
fallback).
Verification is the only cross-leg integrity check (a ZFS scrub
validates one leg against itself). drbd.verify.algorithm (default
crc32c) arms it, and drbd.verify.schedule (5-field cron, e.g.
"0 4 * * 0") runs an online verify of every replicated volume on
that cadence, serialized per node and skipping volumes that are
resyncing. Findings land in the volume's status
(lastVerifyOutOfSyncBytes), the miroir_volume_verify_* metrics,
and a VerifyOutOfSync event; the
starter alerts flag both findings
and a schedule that stopped firing. drbdadm verify <resource> on a
storage node does the same by hand.