Remote consumers and auto-diskful¶
A pod does not have to run on a node that holds a copy of its
volume. Replicated volumes are consumable from any node with a
MiroirNode by default (matching LINSTOR; see the trade-offs below for
the unmapped-node case): the PV carries no node affinity, so the
scheduler is free to place the pod anywhere. When the pod lands on a
node without a replica, it reads and writes the volume over the
replication network through an ephemeral diskless client leg, a
DRBD peer with no local storage. miroir adds that leg to the volume's
spec.clients when the pod's volume is mounted and removes it on
unmount, filling in the connection details (node id, address) exactly
as for an operator-added replica. A pod landing on the tie-breaker's
node needs no client leg; it uses the tie-breaker leg directly.
Set the miroir.home-operations.com/allowRemoteVolumeAccess: "false"
parameter on a StorageClass to opt that class out: its PVs then pin
pods to the diskful replica nodes, guaranteeing local reads.
Trade-offs to understand:
- Every remote read and write crosses the replication network.
Pin latency-sensitive workloads with
allowRemoteVolumeAccess: falseso a replica is always under the pod. - Replica nodes are only preferred at first use. The first consumer's node is pinned as a replica when it is a storage node (capacity-ranked placement otherwise). After that there is no soft preference: PV node affinity is all-or-nothing, so the scheduler is blind to replica locations. Keep locality-sensitive workloads on a pinned class, or steer them with their own node/pod affinity.
- An attached client does not vote in quorum. Client legs are
configured with DRBD's
tiebreaker no(one of the reasons for the 9.3.1 module floor), so attaching and detaching consumers never moves the majority threshold. Once a client leg is removed, the agent also runsdrbdsetup forget-peerfor its node-id on every leg: DRBD keeps a removed peer's metadata slot otherwise and counts it as a missing tiebreaker, which on a 2-replica volume would let a single replica loss drop quorum with the real tie-breaker still connected. - Trims from consumers reach the real backings. A client leg's
device advertises the diskful legs' probed discard granularity
(DRBD's diskless default is a 512-byte fiction dm-thin would
silently drop), so in-pod
fstrimand-o discardfree thin-pool space as if the pod ran on a replica node. - Consumers must run on nodes with a MiroirNode. On an unmapped
node the agent runs only a client-only CSI service (for RWX/NFS
mounts) with no reconciler to realize a DRBD client leg, so staging
refuses with a clear
FailedPreconditionand the pod stays inContainerCreatinguntil it is rescheduled. Keep every schedulable node in the map (aloopfileentry with a few spare GB is enough) or setallowRemoteVolumeAccess: "false"so the PV's node affinity keeps pods on replica nodes in the first place. - A lost node can strand its client leg. Its
spec.clientsentry blocks volume deletion until the node returns or the entry is removed by hand (it holds no quorum vote, so the volume itself stays healthy). - Snapshots work, coordinated through the consumer. Writes originate at the diskless Primary, so the snapshot round raises its write barrier (and the filesystem freeze — the mount lives there too) on the consumer's node first, then cuts the legs on the diskful replicas as usual. The same applies when the consumer stages through a tie-breaker leg.
Auto-diskful¶
Set autoDiskfulAfter (e.g. "10m") to convert a client leg that
has stayed attached past the threshold into a diskful replica on its
node (LINSTOR's auto-diskful). The consumer evidently lives there, so
it gets a local replica and stops paying network I/O: the entry moves
from spec.clients to spec.replicas, and the node's agent attaches
a fresh backing device to the live volume and full-syncs it while the
pod keeps running. Conversion requires the client's node to be in the
topology (a MiroirNode) with recent capacity data and room for the volume's full
size, and the volume to be Ready; a 2+1 volume's
tie-breaker is replaced by the third data copy (three diskful votes
need no tie-breaker). Volumes already at 3 diskful replicas are left
alone; evicting a replica is an operator decision. Empty (the
default) disables it.
On a fully-mapped cluster (every node has a MiroirNode) the volume's
non-replica node is its tie-breaker, so a settled consumer stages
through that leg and no client leg ever exists. Auto-diskful covers
this too: a tie-breaker leg whose device has been held Primary past
the threshold (the agent stamps primarySince from the kernel role)
is flipped diskful in place: node id and address kept, a fresh
backing device attached to the live resource, full-synced under the
running pod.