作業ログ源泉垂れ流し

しがないIT技術者の作業ログを垂れ流す

DRBDの練習 1 〜DRBDのシステム構築〜

DRBD (Distributed Replicated Block Device) を使ってディスクをミラーリングしたシステムを作ってみる。

The DRBD User’s Guideを参考に作業する。
日本語版もあるが、訳が少し怪しいところがあるので、なるべく英語版を参照することにする。

テスト環境としてKVM上にDebian bullseyeのVMを2台作る。 以前の自動インストールの記事を参照。

host$ virt-install --name drbd1 --memory 4096 --vcpus 1 --location $PWD/debian-bullseye-DI-rc1-amd64-netinst.iso --os-variant debiantesting --disk path=drbd1-vda.img,size=5,format=qcow2 --disk path=drbd1-vdb.img,size=10,format=qcow2 --network network=default --graphics none --serial pty --console pty --initrd-inject preseed.cfg --extra-args 'console=ttyS0,115200n8 serial hostname=drbd1 netcfg/get_ipaddress=192.168.122.129 netcfg/get_nameservers=192.168.122.1'
host$ virt-install --name drbd2 --memory 4096 --vcpus 1 --location $PWD/debian-bullseye-DI-rc1-amd64-netinst.iso --os-variant debiantesting --disk path=drbd2-vda.img,size=5,format=qcow2 --disk path=drbd2-vdb.img,size=10,format=qcow2 --network network=default --graphics none --serial pty --console pty --initrd-inject preseed.cfg --extra-args 'console=ttyS0,115200n8 serial hostname=drbd2 netcfg/get_ipaddress=192.168.122.130 netcfg/get_nameservers=192.168.122.1'

OSはvdaにインストールして、10 GiBのvdbは手つかずのまま置いておく。
ホスト名とIPアドレスはマニュアル設定する。

ここからはVM上での作業。

一番最初に、DRBDパッケージをインストールして、有効化する。
Debianの場合

# apt install drbd-utils
# systemctl enable drbd

DRBDの設定ファイルを編集する。 両方のホストで全く同じ内容にする必要がある。

/etc/drbd.d/global_common.confは書き換えなくても使えるが、今回は次のように、レプリケーションのモードに「プロトコルB」を指定した。

common {
        net {   
                protocol B;
        }
}

プロトコルBとは、プライマリノードでの書き込みについて、レプリケーションパケットが対向ノードに届いた時点で書き込み完了とするというもので、

両方のノードに同時に電源障害が起き、かつ、プライマリノードのデータストアに回復不能な破壊があった場合には、最後の書き込みが失われるかもしれない

とのこと (参考)。

続いて、リソース設定ファイル /etc/drbd.d/r0.res を作成する。

resource r0 {
        device          /dev/drbd1;
        disk            /dev/vdb;
        meta-disk       internal;
        on drbd1 {
                address 192.168.122.129:7789;
        }
        on drbd2 {
                address 192.168.122.130:7789;
        }
}

今回はdiskに、2番目の仮想ディスクvdb全体を使う。
IPアドレスは事前に確認しておく。ポート番号は、使われていなければ何でも構わない。

設定ファイルの詳細はマニュアルを参照のこと。

定義したリソース r0 について、はじめて有効化する場合は、最初にデバイスメタデータを作成する。

drbd1# drbdadm create-md r0

次に、リソース r0 を有効化する。

drbd1# drbdadm up r0

リソース r0 のステータスを確認してみる。

drbd1# drbdadm status r0
r0 role:Secondary
  disk:Inconsistent
  peer connection:Connecting

この段階ではInconsistentとなるが問題ない。

drbd2でも全く同じことを行い、 再びステータスを確認してみる。

drbd1# drbdadm status r0
r0 role:Secondary
  disk:Inconsistent
  peer role:Secondary
    replication:Established peer-disk:Inconsistent

依然としてInconsistentだが、replicationEstablishedになっている。

ここまでで、ひとまずリソースr0が準備できたので、サービスを起動する。

drbd1# systemctl start drbd

既に下位デバイスに同期したい内容が書かれている場合には初回のフル同期が必要だが、今回は新しい(仮想)ディスクを使っていて、初回にフル同期する必要はないので、強制的に同期状態に変える。

drbd1# drbdadm new-current-uuid --clear-bitmap r0

この処理は片方のホストだけでやればよい。

再度ステータスを確認してみる。

drbd1# drbdadm status r0
r0 role:Secondary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

drbd2で確認しても、UpToDateになっている。 しかし、どちらのホストもSecondaryになっている。

そこで、書き込みを行いたい側のホストで、プライマリに昇格する。

drbd1# drbdadm primary r0
drbd1# drbdadm status r0
r0 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

drbd2でもステータスを確認してみる。

drbd2# drbdadm status r0
r0 role:Secondary
  disk:UpToDate
  peer role:Primary
    replication:Established peer-disk:UpToDate

drbd1がプライマリ、drbd2セカンダリとして同期されている。

DRBDで作られたデバイスの状態を確認してみる。

drbd1# fdisk -l /dev/drbd1
Disk /dev/drbd1: 10 GiB, 10737053696 bytes, 20970808 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

プライマリのdrbd1では、ちゃんとディスクデバイスとして見えている。

drbd2# fdisk -l /dev/drbd1
fdisk: cannot open /dev/drbd1: Wrong medium type

セカンダリdrbd2だと怒られた。

プライマリのdrbd1/dev/drbd1ファイルシステムを作って、マウントする。

drbd1# mkfs.ext4 /dev/drbd1
mke2fs 1.46.2 (28-Feb-2021)
Discarding device blocks: done                            
Creating filesystem with 2621351 4k blocks and 655360 inodes
Filesystem UUID: bd340ca5-5981-4ba6-8bf3-94c61c16b7b4
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

drbd1# mount /dev/drbd1 /mnt

書き込み性能をddを使って簡単にテストしてみる。

drbd1# dd if=/dev/zero of=/tmp/test bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.6066 s, 1.8 GB/s
drbd1# dd if=/dev/zero of=/mnt/test bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.58761 s, 676 MB/s

DRDBを使っていない/tmpへの書き込みに比べて約4割ほどの速度。

同期されていることを確認する。
まずdrbd1セカンダリに降格する。

drbd1# umount /mnt
drbd1# drbdadm secondary r0
drbd1# drbdadm status r0
r0 role:Secondary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

次にdrbd2をプライマリに昇格する。

drbd2# drbdadm primary r0
drbd2# drbdadm status r0
r0 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

マウントしてファイルを確認。

drbd2# mount /dev/drbd1 /mnt
drbd2# ls /mnt/
lost+found  test

先ほどの性能テストで作られたファイルが存在している。
testファイルを削除して、セカンダリに戻す。

drbd2# rm /mnt/test 
drbd2# umount /mnt
drbd2# drbdadm secondary r0
drbd2# drbdadm status r0
r0 role:Secondary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

そして再びdrbd1をプライマリに昇格して中身を確認。

drbd1# drbdadm primary r0
drbd1# drbdadm status r0
r0 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

drbd1# mount /dev/drbd1 /mnt
drbd1# ls /mnt/
lost+found

DRBDで2ホスト間のディスクが同期できた!