Amazon LinuxでDRBD 8.3.11を構築する
DRBDとは
DRBD(Distributed Replicated Block Device)は、ネットワークを通じてストレージ(ブロックデバイス)をリアルタイムに複製するソフトウェアです。この複製をレプリケーションといいまして、DRBDには3つのモードがあります。デフォルト設定では、同期レプリケーションを行います。同期は、ファイル単位ではなくブロックデバイス単位で必要最小限のデータのみ同期しますから効率が良いです。DRBDインストール後に、/etc/drbd.d/global_common.confを確認すると同期方法を確認できます。
- プロトコルA:非同期レプリケーション
- プロトコルB:メモリ同期(準同期)レプリケーション
- プロトコルC:同期レプリケーション
今回は、Amazon Linux上にDRBDを構築して動作確認をしてみたいと思います。
セットアップ前の準備
まず、プライマリとセカンダリを設定するために2つのインスタンスを用意します。また、それぞれのインスタンスにEBSボリュームを1つ追加しておきます。Management Console等でEBSボリュームを作成してマウントしてください。これが同期用のデバイスとなります。Linux内ではxdvfという名前で登録されると思います。
$ ls /dev/xvdf
また、yumで各種ソフトウェアやカーネルを最新版にしておきましょう。
$ sudo yum update -y
DRBDのインストール
実は、Amazon Linuxには、初めからカーネルレベルでDRBDモジュールが入っています。確認をしてみます。
$ modprobe -l | grep drbd kernel/drivers/block/drbd/drbd.ko $ modinfo drbd | grep version version: 8.3.11 srcversion: 2D876214BAAD53B31ADC1D6
で、このカーネルにインストールされているバージョンと同じものを、ユーザーランドにインストールします。ここからがハマったところだったのですが、yumでインストールするとカーネルよりも新しいバージョンをインストールしてしまいます。私が試したところ、カーネルが8.3.11で、ユーザーランドが8.3.13でした。バージョンが異なるとDRBDを起動できません。そこで、rpmを取得して手動でインストールします。
$ sudo rpm -Uvh http://elrepo.org/linux/elrepo/el5/x86_64/RPMS/drbd83-utils-8.3.11-1.el5.elrepo.x86_64.rpm $ sudo modprobe -v drbd insmod /lib/modules/3.2.21-1.32.6.amzn1.x86_64/kernel/drivers/connector/cn.ko insmod /lib/modules/3.2.21-1.32.6.amzn1.x86_64/kernel/lib/lru_cache.ko insmod /lib/modules/3.2.21-1.32.6.amzn1.x86_64/kernel/drivers/block/drbd/drbd.ko
さらにこれだけでも足りません。rpmで8.3.11をインストールした後にyum updateを行ってしまうと更新してしまいます。そこで、yum update時の除外ルールを設定します。
# vi /etc/yum.conf [main] exclude= *drbd*
インストールされているか、自動起動するか、確認してみましょう。
$ chkconfig --list drbd drbd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
DRBDの初期設定
インストールが完了しましたので続いて同期するデバイスの設定を行います。以下のコマンドは、ループバックデバイスの作成を行っています。ループバックデバイスとは、普通のファイルをあたかもデバイスのように扱う機能です。ddで空ファイルを作成し、losetupで関連づけを行っています。
$ sudo dd if=/dev/zero of=/var/drbd-meta bs=1M count=128 128+0 records in 128+0 records out 134217728 bytes (134 MB) copied, 0.296614 s, 452 MB/s $ sudo losetup /dev/loop0 /var/drbd-meta
続きまして、DRBDの設定ファイルを記述します。設定ファイルの場所は、/etc/drbd.d/内に記述します。global_common.confは全体設定で、.resファイルが個別設定です。今回は、drbd_res0.resというファイルを作成しました。deviceは、後でマウントして使うデバイス名を書きます。diskは、EBSでアタッチしたボリュームのデバイス名を書きます。meta-diskはループバックデバイスで作成したデバイス名です。onブロックは、プライマリとセカンダリのインスタンス情報を書きます。internalなホスト名を書いてください。ホスト名で.ap-northeast-1.compute.internalまでドメインで書くと反応しませんでした。publicドメインやIPを指定すると通信料金が多く掛かってしまいますので避けましょう。以下は記述例です。drbdが同期を行う際に使うポート番号として7788番を指定していますので、EC2のセキュリティグループで7788番での通信を許可してください。同一セキュリティグループからの7788番アクセスを許可すれば良いかと思います。
$ sudo vi /etc/drbd.d/drbd_res0.res resource drbd_res0 { syncer {rate 50M;} device /dev/drbd0; disk /dev/xvdf; meta-disk /dev/loop0[0]; on ip-10-150-179-XXX { address 10.150.179.XXX:7788; } on ip-10-146-101-YYY { address 10.146.101.YYY:7788; } }
ここまで設定がうまく行っていればDRBDの管理ツールを使ってメタデータを作成できるはずです。
$ sudo drbdadm create-md drbd_res0 --== Thank you for participating in the global usage survey ==-- The server's response is: you are the 1681th user to install this version Writing meta data... initializing activity log NOT initialized bitmap New drbd meta data block successfully created. success
DRBDの起動
全て整いました!それでは、DRBDを起動しましょう。片方のインスタンスで起動すると、もう片方のインスタンスでのDRBD起動待ちとなります。全て同じようにもうひとつのインスタンスで設定を行って起動してください。すると、待ち状態から動作確認ができたということでコンソールに復帰します。
$ sudo service drbd start --== Thank you for participating in the global usage survey ==-- The server's response is: node already registered Starting DRBD resources: [ ].........
両方のインスタンスがちゃんと動いているか確認してみましょう。いくつかコマンドが提供されています。
$ sudo service drbd status drbd driver loaded OK; device status: version: 8.3.11 (api:88/proto:86-96) srcversion: 2D876214BAAD53B31ADC1D6 m:res cs ro ds p mounted fstype 0:drbd_res0 Connected Secondary/Secondary Inconsistent/Diskless C $ sudo drbd-overview 0:drbd_res0 Connected Secondary/Secondary Inconsistent/Diskless C r----- $ sudo cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 2D876214BAAD53B31ADC1D6 0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Diskless C r----- ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:5242624
ポイントは、Secondary/Secondaryという部分です。これもハマりポイントでした。DRBDの場合、プライマリに昇格させてからデバイスをマウントします。そして、ファイルの書き込み操作を行うと裏で同期レプリケーションしてくれるのです。ということで、片方のインスタンスで以下のコマンドを打ちます。両方でやってはダメです。両方プライマリにはなれません。
プライマリとセカンダリ
$ sudo drbdadm -- --overwrite-data-of-peer primary drbd_res0 --== Thank you for participating in the global usage survey ==-- The server's response is:
または
$ sudo drbdadm -- primary drbd_res0
初期動作に置いて、--overwrite-data-of-peerオプションを指定すると、ただちに両デバイス間でフル同期作業が始まります。初めてでなければオプションを外しても大丈夫です。プライマリに昇格したか確認してみましょう。
$ sudo cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 2D876214BAAD53B31ADC1D6 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----- ns:0 nr:0 dw:0 dr:664 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
同期レプリケーションの確認
先ほど、drbd_res0.resのdeviceにてデバイス指定をしました。ここに書き込まれた内容が同期されます。そこで、まずはデバイスを初期化してマウントします。xfsファイルフォーマットを使ってみたいと思います。
$ sudo yum install xfs* $ sudo mkfs.xfs /dev/drbd0 meta-data=/dev/drbd0 isize=256 agcount=4, agsize=327680 blks = sectsz=512 attr=2 data = bsize=4096 blocks=1310720, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0
マウントするディレクトリーを作成します。そして、マウントします。
$ sudo mkdir /data $ sudo mount /dev/drbd0 /data
ファイルを書き込んでみましょう。
$ sudo touch /data/hello.txt $ ls /data hello.txt
これで、裏側ではプライマリとセカンダリの間で同期レプリケーションが行われています。DRBDの同期レプリケーションは、プライマリとセカンダリへの同期が全て終わってから書き込み完了となります。ブロックデバイス単位での同期ですので、ユーザやプロセスが考慮する必要がなく、いつもと同じようにマウントしたデバイスを使えるのがDRBDの良いところですね。
セカンダリを昇格させる
セカンダリをプライマリへ昇格させて、もう片方のインスタンスにデータが同期されているか確認します。まずは、プライマリのデバイスをアンマウントしてセカンダリへ降格させます。
$ sudo umount /data $ sudo drbdadm secondary drbd_res0 $ sudo cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 2D876214BAAD53B31ADC1D6 0: cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r----- ns:2077 nr:0 dw:2077 dr:1149 al:2 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
プライマリ/セカンダリだったものが、セカンダリ/セカンダリになりました。次にもう片方のインスタンスから以下のコマンドでプライマリへ昇格させます。
$ sudo cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 2D876214BAAD53B31ADC1D6 0: cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r----- ns:0 nr:2077 dw:2077 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0 $ sudo drbdadm primary drbd_res0 $ sudo cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 2D876214BAAD53B31ADC1D6 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----- ns:0 nr:2077 dw:2077 dr:664 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0 $ sudo mount /dev/drbd0 /data
そして、最後のデータ確認です!!!!
$ ls /data hello.txt
やったーーー、できたーーー!
まとめ
いやぁ、時間掛かったよw。DRBDよりもLinuxの操作理解に時間掛かった。例えば、アンマウントできなくって困っていたら、自分がそのディレクトリに居たとか、カーネルバージョンとユーザーランドバージョンが異なっていたとか、yum updateで勝手に更新されないようにするとか。さらに、AWS部分では、ルートデバイスではなくアタッチしたEBSを使っていたり、internalのIPを使う部分であったり、2つのインスタンスを違うデータセンターに置いたり(Availability Zone)とか。他にも伝えたいことはたくさんあるのですが、続きは次回ということでお楽しみに。今日から君も同期レプリケーションマスターだぁ!
参考資料
[RHEL][DRBD] Linux+DRBDで作るサーバ冗長構成