Distributed Replicated Block Device (DRBD) is a tool for data replication at the block level between servers.
drbd-utils
is the package for managing and configuring
DRBD. The package provides the below commands:
drbdadm
: Manage resources (configure, start/stop,
promote/demote).drbdsetup
: Low-level control for debugging/custom
setups.drbdmeta
: Manage DRBD metadata (create, inspect,
remove).drbdmon
: Monitor real-time states and sync
progress.Set up DRBD to replicate a partition between two hosts:
node1$ apt install drbd-utils
node2$ apt install drbd-utils
{ usage-count no; }
global { syncer { rate 100M; } }
common
{
resource r0 ;
protocol C{
startup -timeout 15;
wfc-wfc-timeout 60;
degr}
{
net -hmac-alg sha1;
cram-secret "secret";
shared}
{
on node1 /dev/drbd0;
device /dev/sda9;
disk 192.168.122.122:7788;
address -disk internal;
meta}
{
on node2 /dev/drbd0;
device /dev/sda9;
disk 192.168.122.28:7788;
address -disk internal;
meta}
}
flowchart TD node1_drbd0["/dev/drbd0"] node2_drbd0["/dev/drbd0"] subgraph node1 node1_sda9["/dev/sda9"] node1_sda9 <---> node1_drbd0 end subgraph node2 node2_sda9["/dev/sda9"] node2_sda9 <---> node2_drbd0 end node1_drbd0 <---> node2_drbd0
/dev/sda9
is the existing partition./dev/drbd0
is drbd partition, no need to be
pre-existing, it will be created automatically by drbd service./dev/sda9
serves as the underlying storage for
/dev/drbd0
.
node1$ drbdadm create-md r0
node2$ drbdadm create-md r0
node1$ systemctl start drbd
# syslog
node1 systemd: Starting drbd.service
node1 drbd: [
node1 drbd: create res: r0
node1 drbd: prepare disk: r0
node1 kernel: block drbd0: disk( Diskless -> Attaching )
node1 kernel: block drbd0: disk( Attaching -> Inconsistent )
node1 drbd: adjust disk: r0
node1 drbd: adjust net: r0
node1 kernel: drbd r0: conn( StandAlone -> Unconnected )
node1 drbd: ]
node1 kernel: drbd r0: conn( Unconnected -> WFConnection )
node1 systemd: Finished drdb.service
node2$ systemctl start drbd
# syslog
# node2 starts service
node2 systemd: Starting drbd.service
node2 drbd: [
node2 drbd: create res: r0
node2 drbd: prepare disk: r0
node2 kernel: block drbd0: disk( Diskless -> Attaching )
node2 kernel: block drbd0: disk( Attaching -> Inconsistent )
node2 drbd: adjust disk: r0
node2 drbd: adjust net: r0
node2 kernel: drbd r0: conn( StandAlone -> Unconnected )
node2 drbd: ]
node2 kernel: drbd r0: conn( Unconnected -> WFConnection )
# node2 handshakes node1
node2 kernel: drbd r0: Handshake sucessfull
node2 kernel: drbd r0: conn( WFConnection -> WFReportParams )
node2 kernel: block r0: peer( Unknown -> Secondary ), conn( WFReportParams -> Connected ), pdsk( DUnknown -> Inconsistent )
node2 systemds: Finish drbd.service
# node1 handshakes node2
node1 kernel: drbd r0: Handshake sucessfull
node1 kernel: drbd r0: conn( WFConnection -> WFReportParams )
node1 kernel: block r0: peer( Unknown -> Secondary ), conn( WFReportParams -> Connected ), pdsk( DUnknown -> Inconsistent )
node1 systemds: Finish drbd.service
node1$ drbdadm -- --overwrite-date-of-peer primary all
# syslog
# node1 becomes sync source
node1 kernel: block drbd0: role( Secondary -> Primary ) disk( Inconsistent -> UpToDate )
node1 kernel: block drbd0: conn( Connected -> WFBitMapS )
node1 kernel: block drbd0: conn( WFBitMapS -> SyncSource )
# node2 becomes sync target
node2 kernel: block drbd0: peer( Secondary -> Primary ) disk( Inconsistent -> UpToDate )
node2 kernel: block drbd0: conn( Connected -> WFBitMapT )
node2 kernel: block drbd0: conn( WFBitMapT -> WFSyncUUID )
node2 kernel: block drbd0: conn( WFSyncUUID -> SyncTarget )
# sync done.
node1 kernel: block drbd0: conn( SyncSource -> Connected ) pdsk (Inconsistent -> UpToDate )
node2 kernel: block drbd0: conn( SyncTarget -> Connected ) pdsk (Inconsistent -> UpToDate )
$ watch -n1 cat /proc/drbd
$ drbdadm status
node1$ lsblk -f
NAME FSTYPE MOUNTPOINTS
sda
├─ sda8 ext4 /home
└─ sda9 drbd
└─ drbd0
node2$ lsblk -f
NAME FSTYPE MOUNTPOINTS
sda
├─ sda8 ext4 /home
└─ sda9 drbd
└─ drbd0
$ mkfs.ext3 /dev/drbd0
node1$ mkdir /mnt/test
node1$ mount /dev/drbd0 /mnt/test
Notes: the drbd partition can only be mounted on the primary node.
node1$ touch /mnt/test/hello
node1$ systemctl stop drbd
# syslog
# node1 stops drbd
node1 systemd: Stopping drbd.service
node1 kernel: EXT4-fs (drbd0): unmounting filesystem
node1 drbd: Stopping all DRBD resources
node1 kernel: block drbd0: role( Primary -> Secondary )
node1 kernel: drbd r0: peer( Secondary -> Unknown ), conn(Connected -> Disconnecting ) pdsk( UpToDate -> DUnknown )
node1 kernel: drbd r0: conn( Disconnecting -> StandAlone )
node1 kernel: drbd r0: disk( UpToDate -> Failed )
node1 kernel: drbd r0: disk( Failed -> Diskless )
node1 systemds: Stopped drbd.service
# node2 updates state
node2 kernel: block drbd0: peer( Primary -> Secondary)
node2 kernel: drbd r0: peer( Secondary -> Unknown ) conn( Connected -> TearDown ) pdsk( UpToDate -> DUnknown )
node2 kernel: drbd r0: conn( TearDown -> Unconnected )
node2 kernel: drbd r0: conn( Unconnected -> WFConnection )
node2$ drbdadm primary r0
# syslog
node2 kernel: block drbd0: role( Secondary -> Primary )
node2$ mount /dev/drbd0 /mnt/test
node2$ ls /mnt/test
hello