【2023年06月版】Ubuntu22.04 上での DRBD によるストレージレプリケーション 構築編

# はじめに

- 絶対に１ミリでもなくしてはいけないデータを手軽に管理したい
- 共有ディスクによるレプリケーションはお高い・・・ソフトウェアでできないものか
- オンプレだけでなく、AWS上でもレプリケーションしたい
- EBS利用である程度保証されるが、A-Zをまたいでストレージレプリケーションしたい
- そうだ DRBD しよう
- の、2023年06月版
- の、論理ディスクを使わずにディスク全体で行う版

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/e2708e2c-99b9-7e8f-5d62-e976cabbe37c.png)

まとめはこちら

[【2023年06月版】Ubuntu22.04 上での DRBD によるストレージレプリケーション](https://qiita.com/nouernet/items/31536b9f63837b0c9001)

# 前提条件

- 2台の ubuntu 22.04 で構築
- Primary を node1、Secondary を node2 とする
- /dev/sda をシステム、/dev/sdb をストレージレプリケーションとして利用
- node1 の IPアドレスは 192.168.100.101 とする
- node2 の IPアドレスは 192.168.100.102 とする
- drbdで作成されるデバイスは、/dev/drbd0 とする
- マウント先は /export とする
- 今回は論理ボリュームを使わずに、デバイスをまるごとレプリケーションする
- hostsは、設定しなくてもできることがわかったので設定しない

# 手順

- DRBD のインストール
- 設定ファイルを作成
- メタデータの作成
- DRBD の起動
- Primary の決定
- マウント
 
# 作業

## DRBD のインストール

- node1, node2 で実行

```terminal
$ sudo add-apt-repository ppa:linbit/linbit-drbd9-stack
$ sudo apt update
$ sudo apt install drbd-utils drbd-dkms
$ sudo modprobe drbd
$ cat /proc/drbd
version: 9.2.2 (api:2/proto:86-121)
GIT-hash: 8435da3ec2a0a70dee0fedf354276d6f1c6ba708 build by root@nodeX, 2023-05-26 13:01:35
Transports (api:18): tcp (9.2.2)
```

- arm64版だと以下の感じ

```terminal
cat /proc/drbd
version: 9.2.2 (api:2/proto:86-121)
GIT-hash: 8435da3ec2a0a70dee0fedf354276d6f1c6ba708 build by root@nodeX, 2023-06-10 00:02:57
Transports (api:18): tcp (9.2.2)
```

## 設定ファイルの作成

- node1, node2 で実行

```terminal
$ sudo tee /etc/drbd.d/global_common.conf <<EOF > /dev/null 
global {
    usage-count no;
}
common {
    net {
        protocol C;
    }
}
EOF
```

```terminal
$ sudo tee /etc/drbd.d/r0.res <<EOF > /dev/null 
resource r0 {
    device /dev/drbd0;
    disk /dev/sdb;
    meta-disk internal;
    on node1 {
        address 192.168.100.101:7789;
    }
    on node2 {
        address 192.168.100.102:7799;
    }
}
EOF
```

## メタデータの作成

- node1, node2 で実行

```terminal
$ sudo drbdadm create-md r0
```

## DRBD の起動

- node1, node2 で実行

```terminal
$ sudo drbdadm up r0
$ sudo drbdadm status r0
```

## Primary 決定

- Primary だけで実行

```terminal
$ sudo drbdadm primary r0
$ sudo drbdadm status r0
```

## マウント

- node1(Primary) だけで実行

```terminal
$ sudo mount /dev/drbd0 /export
```

# 動作確認

## DRBD の停止

- node1, node2 で実行

```terminal
$ sudo drbdadm down r0
$ sudo drbdadm status r0
```

## Primaryの切り替え

- Primary(node1) -> Secondary(node2) 、　Secondary(node2) -> Primary(node1)
- 元 Primary(node1) だけで実行

```terminal
$ sudo umount /export
$ sudo drbdadm secondary r0
$ sudo drbdadm status r0
```

- 元 Secondary(node2) だけで

```terminal
$ sudo drbdadm primary r0
$ sudo drbdadm status r0
$ sudo mount /dev/drbd0 /export
```

## サービス化

- node1, node2 で実行

```terminal
$ sudo systemctl enable drbd@r0.target
```

## Primary が逝った、 Secondary を強制的に Primaryに

- Secondary(node2)　で

```terminal
$ sudo drbdadm --force primary r0
$ sudo drbdadm status r0
$ sudo mount /dev/drbd0 /export
```

# その他

## DRBD のメタデータの初期化

```terminal
$ sudo drbdadm create-md r0
You want me to create a v09 style flexible-size internal meta data block.
There appears to be a v09 flexible-size internal meta data block
already in place on /dev/sdb at byte offset 21474832384

Do you really want to overwrite the existing meta-data?
[need to type 'yes' to confirm] yes

initializing activity log
initializing bitmap (640 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
```

## デバイスに書き込み

ファイルシステムを壊す時、大きなファイルを書き込む等に利用

### ZERO データの書き込み

```terminal
$ sudo dd if=/dev/zero of=/dev/sdb bs=1G count=10
```

### RANDOM データの書き込み

```terminal
$ sudo dd if=/dev/random of=/export/10G_FILE bs=1G count=10
```

# エラーになる

## `# No currently configured DRBD found.`

- `/etc/drbd.d/global_common.conf` の存在を確認する
- `/etc/drbd.d/global_common.conf` の記述を確認する
- `/etc/drbd.d/r0.res` の存在を確認する
- `/etc/drbd.d/r0.res` の記述を確認する
    - host名は一致しているか(on node1の箇所)
    - ipアドレスは一致しているか
    - diskで記述しているデバイスは存在するか(/dev/sdb等)
- drbdのバージョンを確認する
    - drbdがロードできていない場合
        ```terminal
        $ cat /proc/drbd
        cat: /proc/drbd: No such file or directory
        ```
- `/etc/drbd.d/drbd.conf` を間違えて書き換えていないか確認する
    - デフォルトのdrbd.conf
        ```terminal
        $ cat /etc/drbd.conf 
        # You can find an example in  /usr/share/doc/drbd.../drbd.conf.example
        
        include "drbd.d/global_common.conf";
        include "drbd.d/*.res";
        ```

## `drbdadm create-md` がエラーになる
- 以下のようなエラーが表示された場合
    ```terminal
    $ sudo drbdadm create-md r0
    md_offset 2143285248
    al_offset 2143252480
    bm_offset 2143186944
    
    Found xfs filesystem
         2093056 kB data area apparently used
         2092956 kB left usable by current configuration
    
    Device size would be truncated, which
    would corrupt data and result in
    'access beyond end of device' errors.
    You need to either
       * use external meta data (recommended)
       * shrink that filesystem first
       * zero out the device (destroy the filesystem)
    Operation refused.
    
    Command 'drbdmeta 0 v09 /dev/sdb internal create-md 1' terminated with exit code 40
    ```

- この場合は、xfsでフォーマットされているので怒られている。削除することを前提に、`dd` でデバイスの先頭をふっとばすとよい
    
    ```terminal
    $ sudo dd if=/dev/zero of=/dev/sdb bs=1024 count=1024 status=progress
    1024+0 records in
    1024+0 records out
    1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.0176674 s, 59.4 MB/s
    ```

# 余談

- drbdがlistenしているポートが`ss`, `netstat` で見つからない、なんでや・・・
    - `ss`, `netstat` しても、listenポートがみつからない
        ```terminal
        $ sudo ss -anlt | grep 7789
        $ sudo netstat -anlt | grep 7789
        ```
    - `ss -ant | grep 7789` でみつかる
        DRBDで接続が確立されるとlistenしなくなる仕様の模様
        ```terminal
        $ sudo ss -ant | grep 7789
        ESTAB  0      0      192.168.100.101:7789  192.168.100.102:40279
        ```
    - 例： primary を落として secondary で `ss` で、listen を確認できる
        ```terminal
        $ sudo ss -anlt | grep 7799
        LISTEN 0      64     192.168.100.102:7799       0.0.0.0:*   
        ```
- drbdがlistenしているポートが`lsof` で見つからない、`ss`, `netstat` ではみつかる、なんでや・・・
    - `lsof` しても、listenポートがみつからない
        ```terminal
        $ sudo ss -anlt | grep 7799
        LISTEN 0      64     192.168.100.102:7799       0.0.0.0:*   
        $ sudo netstat -anlt | grep 7789
        tcp        0      0 192.168.100.102:7799    0.0.0.0:*               LISTEN 
        $ sudo lsof -i :7799
        ```
    - `ss`, `netstat` で inode をみつけて、そこから `lsof` してみるけど、みつからん、なんでや・・・
        ```terminal
        $ sudo ss -anlte | awk 'NR==1 || /7799/'
        State  Recv-Q Send-Q   Local Address:Port  Peer Address:PortProcess
        LISTEN 0      64     192.168.100.102:7799       0.0.0.0:*    ino:35957 sk:9 cgroup:/ <->
        $ sudo netstat -anlte | awk 'NR==1 || NR==2 || /7799/'
        Active Internet connections (servers and established)
        Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode     
        tcp        0      0 192.168.100.102:7799    0.0.0.0:*               LISTEN      0          35957
        $ sudo lsof | grep 35957
        ```
    - AIに聞いた答え：　drbdはカーネルモジュールなので `lsof` では表示されない。統計の `ss` や `netstat` では表示される。

# さいごに

- かんたんでしたね

# 参考

[Ubuntu 22.04 man page drbdadm](https://manpages.ubuntu.com/manpages/jammy/ja/man8/drbdadm.8.html)
[Ubuntu 22.04 man page drbd](https://manpages.ubuntu.com/manpages/jammy/ja/man8/drbd.8.html)

[DRBD9 ユーザーズガイド](https://linbit.com/drbd-user-guide/drbd-guide-9_0-ja/)
[LINSTOR ユーザーズガイド](https://linbit.com/drbd-user-guide/linstor-guide-1_0-ja/)