Heartbeat v3 + Pacemaker 再び

前回は2台のサーバをアクティブ・スタンバイとしてクラスタリングしただけなので話は簡単(でもなかったけど)。

今回の構成では、2台のサーバで1台はWeb、1台はDBが動いていて、それぞれがフェイルオーバーするようにしてみる。
とは言っても、Pacemakerの設定ファイルが長くなるだけで、やることはあまり変わらなかった。

Heartbeat v3 に関して詳細に記述してるサイトが少ないので、
インストール手順も含めて詳細に記述してみる。

要件

node1:Apacheが稼働
node2:PostgreSQLが稼働

node1故障時には、node2でApache+PostgreSQL
node2故障時には、node1でPostgreSQL+Apache

となるように。

node1:eth0=192.168.0.101 / eth1=172.23.5.101
node2:eth0=192.168.0.102 / eth1 = 172.23.5.102
仮想IPとして、Web用に192.168.0.100(eth0側)、DB用に172.23.5.100(eth1側)を使用。

OSはCentOS5.5

DRBDインストール・設定

まずはnode1側の作業。
HDDの空き領域にパーティションを作成。

#> fdisk /dev/sda
コマンド (m でヘルプ): p
/dev/sda1   *           1       10199    81923436   83  Linux
/dev/sda2           10200       10326     1020127+  82  Linux swap / Solaris

DRBDで使用するパーティションを作成

コマンド (m でヘルプ): n
コマンドアクション
   e   拡張
   p   基本領域 (1-4)
p
領域番号 (1-4): 3
最初 シリンダ (10327-60734, default 10327): 10327
終点 シリンダ または +サイズ または +サイズM または +サイズK (10327-60734, default 60734): 35530

コマンド (m でヘルプ): n
コマンドアクション
   e   拡張
   p   基本領域 (1-4)
p
領域番号 (1-4): 4
最初 シリンダ (35531-60734, default 35531): 35531
終点 シリンダ または +サイズ または +サイズM または +サイズK (10327-60734, default 60734): 60734

コマンド (m でヘルプ): w
領域テーブルは交換されました!

コマンド (m でヘルプ): p
デバイス Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1       10199    81923436   83  Linux
/dev/sda2           10200       10326     1020127+  82  Linux swap / Solaris
/dev/sda3           10327       35530   202451130   83  Linux
/dev/sda4           35531       60734   202451130   83  Linux

それぞれ200GBづつのパーティションを作って、それぞれにWebとDBのデータを配置。
マウントポイントは、/var/www と /var/pgsql にする。

drbdのインストール

#>yum install drbd83 kmod-drbd83

インストールしたdrbdが対応しているカーネルバージョンを確認

#>rpm -qi kmod-drbd83
kernel 2.6.18-194.el5 for the i686 family of processors.

現在のカーネル

#>uname -r
2.6.18-194.32.1.el5PAE

カーネルバージョンが違うので、対応カーネルを再インストール

#>yum -y install yum-allowdowngrade
#>yum --allow-downgrade -y install kernel-2.6.18-194.el5

/etc/grub.confを確認

default=2
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-194.el5)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-194.el5 ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-194.el5.img
title CentOS (2.6.18-194.32.1.el5)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-194.32.1.el5 ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-194.32.1.el5.img
title CentOS (2.6.18-194.32.1.el5PAE)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-194.32.1.el5PAE ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-194.32.1.el5PAE.img
title CentOS (2.6.18-194.el5PAE)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-194.el5PAE ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-194.el5PAE.img

インストールしたカーネルがデフォルトでロードされるように、default=の値を変更
上から順番に0、1、2となってる。default=0にして、リブート。

確認

#>uname -r
2.6.18-194.el5

/etc/drbd.confを編集

global { usage-count yes; }
common { syncer { rate 10M; } }
#Web用のDRBDリソース設定
resource web {
  protocol C;
  startup {
        degr-wfc-timeout 120;
  }
 net {
        cram-hmac-alg sha1;
        shared-secret "hogehoge";
  }
  on node1{
        device /dev/drbd0;
        disk /dev/sda3;
        address 172.23.5.101:7789;
        meta-disk internal;
  }
  on node2{
        device /dev/drbd0;
        disk /dev/sda3;
        address 172.23.5.102:7789;
        meta-disk internal;
  }
}

#DB用のDRBDリソース設定
resource db {
  protocol C;
  startup {
        degr-wfc-timeout 120;
  }
 net {
        cram-hmac-alg sha1;
        shared-secret "hogehoge";
  }
  on node1{
        device /dev/drbd1;
        disk /dev/sda4;
        address 172.23.5.101:7790;
        meta-disk internal;
  }
  on node2{
        device /dev/drbd1;
        disk /dev/sda4;
        address 172.23.5.102:7790;
        meta-disk internal;
  }
}

DRBDメタデータ作成

#> drbdadm create-md web
#> drbdadm create-md db

初期同期をスキップ

#> drbdadm -- 6::::1 set-gi web
#> drbdadm dump-md web > /tmp/md
#> sed -i -r -e 's/0xF{16}/0x0000000000000000/g' /tmp/md
#> drbdmeta /dev/drbd0 v08 /dev/sda3 internal restore-md /tmp/md ; rm -f /tmp/md
#>
#> drbdadm -- 6::::1 set-gi db
#> drbdadm dump-md db > /tmp/md
#> sed -i -r -e 's/0xF{16}/0x0000000000000000/g' /tmp/md
#> drbdmeta /dev/drbd1 v08 /dev/sda4 internal restore-md /tmp/md ; rm -f /tmp/md

なんか聞かれたらとりあえずyes
ここまでをnode2側でも同様に行う

node1、node2の両方でDRBD起動

#>chkconfig --add drbd
#>service drbd start

ファイルシステム(ext3)作成
node1:

#> drbdadm primary web
#>/etc/rc.d/init.d/drbd status
drbd driver loaded OK; device status:
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by mockbuild@builder10.centos.org, 2010-06-04 08:04:16
m:res  cs         ro                 ds                 p  mounted  fstype
0:web   Connected  Primary/Secondary  UpToDate/UpToDate  C  ←webはnode1がprimary
1:db   Connected  Secondary/Secondary  UpToDate/UpToDate  C
#>mkfs -t ext3 /dev/drbd0

node2:

#> drbdadm primary db
#>/etc/rc.d/init.d/drbd status
drbd driver loaded OK; device status:
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by mockbuild@builder10.centos.org, 2010-06-04 08:04:16
m:res  cs         ro                 ds                 p  mounted  fstype
0:web   Connected  Secondary/Primary  UpToDate/UpToDate  C
1:db   Connected  Primary/Secondary  UpToDate/UpToDate  C
#>mkfs -t ext3 /dev/drbd1

動作確認
node1:

#> mount /dev/drbd0 /var/www
#> touch /var/www/hoge.txt
#> umount /var/www
#> drbdadm secondary web

node2:

#> drbdadm primary web
#> mount /dev/drbd0 /var/www
#> ls /var/www
drwxr-xr-x  3 root root 4096  2月14  2011 hoge.txt
#>umount /var/www

Heartbeat v3 + Pacemaker

epelがyumで自動で入らないので、事前にいれておく

#>wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
#>rpm -ivh epel-release-5-4.noarch.rpm

2011/2/14現在、yumでheartbeatをインストールするとv2になるので、v3のレポジトリを入れておく
Linux-HA Japanが提供)

#>wget http://iij.dl.sourceforge.jp/linux-ha/49890/pacemaker-1.0.10-1.4.1.el5.i386.repo.tar.gz
#>mv pacemaker-1.0.10-1.4.1.el5.i386.repo.tar.gz /tmp
#>tar -zxf /tmp/pacemaker-1.0.10-1.4.1.el5.i386.repo.tar.gz
#>cd /tmp/pacemaker-1.0.10-1.4.1.el5.i386.repo
#>yum -c pacemaker.repo install corosync-1.2.5-1.3.el5.i386 heartbeat-3.0.4-1.el5.i386 pacemaker-1.0.10-1.4.el5.i386

/etc/ha.d/ha.cf

pacemaker on
logfacility local1

debug 0
udpport 694

keepalive 2
warntime 20
deadtime 24
initdead 48

ucast eth1 172.23.5.102 ←クラスタリングの相手側のIPアドレス。ここではnode2のIP。

node node1
node node2

watchdog /dev/watchdog

認証ファイル
/etc/ha.d/authkeys

auth 1
1 sha1 password

パーミッションを600

#> chmod 600 /etc/ha.d/authkeys

ログが標準ではsyslogに吐かれるので、別にしておく
/etc.syslog.conf

*.info;mail.none;authpriv.none;cron.none;local1.none            /var/log/messages
local1.*                                                           /var/log/ha-log

ここまでをnode2でも行う。
heartbeatをnode1,node2で起動

#> service heartbeat start
#>crm_mon
============
Last updated: Thu Feb 10 01:17:34 2011
Stack: Heartbeat
Current DC: node1 (43a6ee456af4-188e-4ec8-0a99-4416c25e) - partition wit
h quorum
Version: 1.0.10-da7075976b5ff0bee71074385f8fd02f296ec8a3
2 Nodes configured, unknown expected votes
0 Resources configured.
============

Online: [ node1 node2 ]

pacemakerのリソース設定。
/etc/ha.d/setting.txt

#WebのDRBD設定
primitive drbd_web ocf:linbit:drbd \
        params drbd_resource="web" \
        op start interval="0s" timeout="240s" on-fail="restart" \
        op monitor interval="11s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" role="Master" \
        op stop interval="0s" timeout="100s" on-fail="block"

#DBのDRBD設定
primitive drbd_db ocf:linbit:drbd \
        params drbd_resource="db" \
        op start interval="0s" timeout="240s" on-fail="restart" \
        op monitor interval="11s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" role="Master" \
        op stop interval="0s" timeout="100s" on-fail="block"        

#Webの仮想IPアドレス設定。IP、nic、ネットマスクは環境に合わせて変更
primitive ip_web ocf:heartbeat:IPaddr \
        params ip="192.168.0.100" \
                nic="eth0" \
                cidr_netmask="24" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

#DBの仮想IPアドレス設定。IP、nic、ネットマスクは環境に合わせて変更
primitive ip_db ocf:heartbeat:IPaddr \
        params ip="172.23.5.100" \
                nic="eth1" \
                cidr_netmask="24" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

#nicの死活監視用。ルーター(192.168.0.1)にpingを飛ばす
primitive pingd_web ocf:pacemaker:pingd \
        params \
                name="default_ping_set" \
                host_list="192.168.0.1" \
                multiplier="100" \
                dampen="0" \
        meta \
                migration-threshold="10" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

#同様にeth1側のnic死活監視用。
primitive pingd_db ocf:pacemaker:pingd \
        params \
                name="default_ping_set" \
                host_list="172.23.5.1" \
                multiplier="100" \
                dampen="0" \
        meta \
                migration-threshold="10" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

#Web用のDRBDのマウント情報
primitive fs_web ocf:heartbeat:Filesystem \
        params device="/dev/drbd0" directory="/var/www" fstype="ext3" \
        op start interval="0s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="block"

#DB用のDRBDのマウント情報
primitive fs_db ocf:heartbeat:Filesystem \
        params device="/dev/drbd1" directory="/var/pgsql" fstype="ext3" \
        op start interval="0s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="block"

#PostgreSQLのリソース設定
primitive postgresql ocf:heartbeat:pgsql \
        params pgctl="/usr/local/pgsql/bin/pg_ctl" \
        start_opt="-p 5432 -h 127.0.0.1" \
        psql="/usr/local/pgsql/bin/psql" \
        pgdata="/var/pgsql/data" \
        pgdba="postgres" \
        pgport="5432" \
        pgdb="template1" \
        op start interval="0s" timeout="120s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="120s" on-fail="block"

#Apacheのリソース設定
primitive apache ocf:heartbeat:apache \
        params configfile="/usr/local/apache/conf/httpd.conf" \
        port="80" \
        op start interval="0s" timeout="40s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="block"

#Web用、DB用にそれぞれグループ化
group group_db fs_db ip_db postgresql
group group_web fs_web ip_web apache

#DRBDの設定
ms ms_drbd_db drbd_db \
        meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
        
ms ms_drbd_web drbd_web \
        meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
 
#Ping設定
clone clnPingd_web pingd_web \
        meta clone-max="2" clone-node-max="1"

clone clnPingd_db pingd_db \
        meta clone-max="2" clone-node-max="1"

#どちらがマスターでどちらがスレーブかを設定。ここはDB用なので、node2がマスターになるようにする
location group_db-location group_db \
        rule 200: #uname eq node2 \
        rule 100: #uname eq node1 \
        rule -INFINITY: defined default_ping_set and default_ping_set lt 100

#DB用のDRBDのマスター/スレーブ設定。
location master-location_db ms_drbd_db \
        rule 200: #uname eq node2 \
        rule 100: #uname eq node1 \
        rule role=master -INFINITY: defined default_ping_set and default_ping_set lt 100

#同じくWeb用のマスター/スレーブ設定。node1がマスター
location group_web-location group_web \
        rule 200: #uname eq node1 \
        rule 100: #uname eq node2 \
        rule -INFINITY: defined default_ping_set and default_ping_set lt 100

#Web用のDRBDのマスター/スレーブ設定
location master-location_web ms_drbd_web \
        rule 200: #uname eq node1 \
        rule 100: #uname eq node2 \
        rule role=master -INFINITY: defined default_ping_set and default_ping_set lt 100

#DB用にDRBDをマウントしてから、PostgreSQLを起動
colocation db_on_drbd inf: group_db ms_drbd_db:Master
colocation clnPingd_db-colocation 1000: group_db clnPingd_db
order order_db_after_drbd inf: ms_drbd_db:promote group_db:start

#Web用にDRBDをマウントしてから、Apacheを起動
colocation web_on_drbd inf: group_web ms_drbd_web:Master
colocation clnPingd_web-colocation 1000: group_web clnPingd_web
order order_web_after_drbd inf: ms_drbd_web:promote group_web:start

property $id="cib-bootstrap-options" \
        cluster-infrastructure="openais" \
        expected-quorum-votes="2" \
        no-quorum-policy="ignore" \
        stonith-enabled="false" \
        startup-fencing="false" \
        dc-deadtime="20s"

#フェイルバックしないように
rsc_defaults $id="rsc-options" \
        resource-stickiness="INFINITY" \
        migration-threshold="1"

以下はnode1側だけでOK。node2には自動でHeartbeatが設定を伝えてくれる

#>crm configure
crm(live)configure# load replace /etc/ha.d/setting.txt
crm(live)configure# commit

crm_monをしばらく眺めてると起動の様子が見れる。

Online: [ node1 node2 ]

 Resource Group: group_db
     fs_db	(ocf::heartbeat:Filesystem):    Started node2
     ip_db	(ocf::heartbeat:IPaddr):        Started node2
     postgresql (ocf::heartbeat:pgsql): Started node2
 Resource Group: group_web
     fs_web     (ocf::heartbeat:Filesystem):    Started node1
     ip_web     (ocf::heartbeat:IPaddr):        Started node1
     apache     (ocf::heartbeat:apache):        Started node1
 Master/Slave Set: ms_drbd_db
     Masters: [ node2 ]
     Slaves: [ node1 ]
 Master/Slave Set: ms_drbd_web
     Masters: [ node1 ]
     Slaves: [ node2 ]
 Clone Set: clnPingd_db
     Started: [ node1 node2 ]
 Clone Set: clnPingd_web
     Started: [ node2 ]

StartにFailedしたら、設定ファイルの間違いを確認。Apacheが起動しないときは別記事を参照。
/var/log/ha-logも手がかりになる。
Pacemakerの設定を消すには、heartbeatを停止。

#>rm /var/lib/heartbeat/crm/*

heartbeatを起動、crm configureで設定ファイルを再度ロードすればいい。

/usr/lib/ocf/resource.d/heartbeatを見ると、MySQLPostfixXenvmwareなどいろいろ。
必要なパラメーターは単なるスクリプトファイルなので眺めていればなんとなく分かる。
MailToを使って、フェイルオーバー時にメール送信、みたいなこともできる(はず)。今度やってみよう。

参考サイト:
CentOSで自宅サーバ構築 様
Linux-HA Japan 様