2012年3月17日土曜日

Pacemaker+drbd+heartbeatでMySQLクラスタ

LPIC304の勉強で、Pacemaker+DRBD+heartbeatでMySQLのクラスタ構成を作ってみる。

はじめに

環境は以下の通り。
  • CentOS 5.6
  • drbd83-8.3.12-2.el5.centos
  • heartbeat-3.0.3-2.3.el5
  • pacemaker-1.0.12-1.el5.centos
  • mysql-server-5.0.95-1.el5_7.1
各プロダクトのインストールはyumで出来るので割愛。基本的には公式HPをもとにして、いろいろ補足を入れていきます。

作る環境は以下の通り
  • 共有IP「192.168.4.30」 にMySQLを立てる
  • ノード「db1」
    • サービス用:eth1(192.168.4/24に接続)
    • ヘルスチェック用:eth2(IP:192.168.5.31) 
  • ノード「db2」
    • サービス用:eth1(192.168.4/24に接続)
    • ヘルスチェック用:eth2(IP:192.168.5.32) 

準備

まずDRBDの設定は以下の通り。/etc/drbd.confを編集。 (DRBDの初期化作業は割愛させてもらいます。 )
resource r0 {
    protocol C;
    device /dev/drbd0;
    meta-disk internal;

    on db1 {
        address 192.168.5.31:7801;
        disk /dev/xvdb1;
    }
    on db2 {
        address 192.168.5.32:7801;
        disk /dev/xvdb1;
    }
}


heartbeatの設定は以下の通り。/etc/ha.d/ha.cfを編集。
pacemaker on
logfile /var/log/ha-log
logfacility     local0
keepalive 2
udpport 694
ucast eth2 192.168.5.32 #←db2の方は192.168.5.31
node    db1
node    db2

次に、mysqlのデータディレクトリをDRBDのレプリケーションディレクトリに変える。/etc/my.cnfを編集。
[mysqld]
datadir=/service/mysql  #←DRBDのレプリケーション対象の/service以下にする
(以下略)
ここまでできたら、heartbeatを起動。
# /etc/init.d/heartbeat start
起動したら、crm_monのコマンドで、クラスタの状態を確認。heartbeatが起動すると
============
Last updated: Sat Mar 17 12:01:31 2012
Stack: Heartbeat
Current DC: db2 (88696624-7159-4ad1-bdf3-aac07d645d99) - partition with quorum
Version: 1.0.12-unknown
2 Nodes configured, unknown expected votes
0 Resources configured.
============

Online: [ db1 db2 ]
になる。

これで準備はOK。pacemakerの設定に入っていく。どちらかのノードで、crmのコマンドを実行し、設定ツールを起動。その後configureを入力し、設定モードへ。
[root@db1 ~]# crm
crm(live)# configure
crm(live)configure#
この後は以下の順序で設定していく。
  1. 全体の設定
  2. 共有IPアドレスをリソースとして追加
  3. DRBDをリソースとして追加
  4. ファイルシステム(マウント定義)をリソースとして追加
  5. MySQLをリソースとして追加
  6. リソースのグループ、リソース間の制約・順序の設定

全体の設定

まず全体の設定は、以下コマンドをcrm(live)configure#のプロンプトに打ち込めばOK。
property $id="cib-bootstrap-options" no-quorum-policy="ignore" stonith-enabled="false"
no-quorum-policyは2台構成の場合は必ずignoreにしないといけないらしい。 stonith-enabledは相手が半死にした場合に止めを刺す機能だけど、止めておく。

共有IPアドレスのリソースの追加

次に、共有IPアドレスのリソースの追加
primitive ip_mysql ocf:heartbeat:IPaddr2 params ip="192.168.4.30" nic="eth1"
「ocf」っていうのはOpen Cluster Frameworkの略で、Open Cluster Framework projectが 推奨するタイプのスクリプト。/usr/lib/ocf/resource.d以下にある。
この段階で、一回commitして挙動を確認する。
crm(live)configure# commit
公式HPでは、全部設定してからcommitする手順になっているが、一つ一つ確認したほうが確実なので、こまめにcommitするのがよいと思う。
commitしてしばらくすると、crm_monの表示が以下のように変わる。
============
Last updated: Sat Mar 17 12:20:37 2012
Stack: Heartbeat
Current DC: db2 (88696624-7159-4ad1-bdf3-aac07d645d99) - partition with quorum
Version: 1.0.12-unknown
2 Nodes configured, unknown expected votes
1 Resources configured.
============

Online: [ db1 db2 ]

ip_mysql        (ocf::heartbeat:IPaddr2):       Started db1 (←リソースが追加された)
ifconfigを打つと、確かにdb1のeth1に192.168.4.30が付いていることが分かる(場合によってはdb2につく場合もある)。

DRBDのリソースを追加

次に、DRBDのリソースを追加していく。
primitive drbd_mysql ocf:linbit:drbd params drbd_resource="r0"
ms ms_drbd_mysql drbd_mysql meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
「ms」というのは、マスタースレーブ構成の場合に設定する項目。内容は公式HP参照。
そんでコミットすると、crm_monの表示は以下の通り。(タイムアウトが短いとかいうワーニングが出るが無視)
============
Last updated: Sat Mar 17 12:23:59 2012
Stack: Heartbeat
Current DC: db2 (88696624-7159-4ad1-bdf3-aac07d645d99) - partition with quorum
Version: 1.0.12-unknown
2 Nodes configured, unknown expected votes
2 Resources configured.
============

Online: [ db1 db2 ]

ip_mysql        (ocf::heartbeat:IPaddr2):       Started db1
 Master/Slave Set: ms_drbd_mysql (←リソースが追加された)
     Masters: [ db1 ]
     Slaves: [ db2 ]
確認のために「cat /proc/drbd」を打つと、db1がprimaryになっていることが分かる。

ファイルシステム(マウント定義)のリソースを追加

続いて、ファイルシステムのリソースを追加する。
primitive fs_mysql ocf:heartbeat:Filesystem params device="/dev/drbd/by-res/r0" directory="/service/" fstype="ext3"
そんでコミットすると、crm_monの表示は以下の通り。
============
Last updated: Sat Mar 17 13:34:00 2012
Stack: Heartbeat
Current DC: db2 (88696624-7159-4ad1-bdf3-aac07d645d99) - partition with quorum
Version: 1.0.12-unknown
2 Nodes configured, unknown expected votes
3 Resources configured.
============

Online: [ db1 db2 ]

ip_mysql        (ocf::heartbeat:IPaddr2):       Started db1
 Master/Slave Set: ms_drbd_mysql
     Masters: [ db1 ]
     Slaves: [ db2 ]
fs_mysql        (ocf::heartbeat:Filesystem):    Started db1
確認のために「df」コマンドを打つと、db1でDRBDのパーティションをマウントしていることが分かる。

MySQLのリソースの追加

続いて、MySQLのリソースの追加。
primitive mysqld lsb:mysqld
「lsb」というのは、Linux Standard Baseの略。Linux標準で提供される/etc/init.d以下にある起動スクリプトのこと。

で、コミットするとcrm_monは以下のようになる。
============
Last updated: Sat Mar 17 13:35:23 2012
Stack: Heartbeat
Current DC: db2 (88696624-7159-4ad1-bdf3-aac07d645d99) - partition with quorum
Version: 1.0.12-unknown
2 Nodes configured, unknown expected votes
4 Resources configured.
============

Online: [ db1 db2 ]

ip_mysql        (ocf::heartbeat:IPaddr2):       Started db1
 Master/Slave Set: ms_drbd_mysql
     Masters: [ db1 ]
     Slaves: [ db2 ]
fs_mysql        (ocf::heartbeat:Filesystem):    Started db1
mysqld  (lsb:mysqld):   Started db1  (←追加された)
SELinuxが動いていると、別パーティションへのデータ保存はできないため、MySQLの起動エラーになる可能性あり。SELinuxを切ればOK

リソースのグループ、リソース間の制約・順序の設定

最後に、リソースのグループ、リソース間の制約・順序の設定する。
group     mysql fs_mysql ip_mysql mysqld
colocation mysql_on_drbd inf: mysql ms_drbd_mysql:Master
order      mysql_after_drbd inf: ms_drbd_mysql:promote mysql:start
設定の意味は、
  • 1行目は「ファイルシステムと共有IPとMySQLをグループ『mysql』に指定」
  • 2行目は「mysqlグループとDRBDのマスターは同時に存在しなくてはならない」
  • 3行目は「DRBDのマスターが起動した後に、mysqlグループが起動しなくてはならない」
この指定によって、仮にちぐはぐにリソースが配置されいたとしても、上記の制約に従って自動的に再配置が行われる。
この「inf:」という文字列は謎で、公式HPを読んでも何も書いていない(筆者はInfinityの略ではないかと思っている)。よくわからないので、仕方なくいわれるがままに指定している。せめて公式HPにはオプションの意味ぐらい書いてほしいところだ。

最終的にcrm_monは以下のようになる。
============
Last updated: Sat Mar 17 13:36:23 2012
Stack: Heartbeat
Current DC: db2 (88696624-7159-4ad1-bdf3-aac07d645d99) - partition with quorum
Version: 1.0.12-unknown
2 Nodes configured, unknown expected votes
2 Resources configured.
============

Online: [ db1 db2 ]

 Master/Slave Set: ms_drbd_mysql
     Masters: [ db1 ]
     Slaves: [ db2 ]
 Resource Group: mysql (←まとまった)
     fs_mysql   (ocf::heartbeat:Filesystem):    Started db1
     ip_mysql   (ocf::heartbeat:IPaddr2):       Started db1
     mysqld     (lsb:mysqld):   Started db1

設定のリセット

ちなみに、設定に失敗した場合は、以下の手順でリセットできる。
# /etc/init.d/heartbeat stop
# rm -rf /var/lib/heartbeat/crm/*

2012年3月10日土曜日

XenカーネルでDRBDを使うときにハマったこと

CentOS5.6(xenカーネル)で、DRBDを動かそうと思い、drbdをyumでインストール。
# yum install drbd83.i386 kmod-drbd83.i686
色々設定後、サービスの起動で以下のようなエラーメッセージが出た。
# /etc/init.d/drbd start
Starting DRBD resources: Can not load the drbd module.
どうやら、普通のDRBDのカーネルモジュール(kmod-drbd83)はxen環境では動作しないようだ。
 冷静に考えれば、カーネルが違うんだから、モジュールも違って当たり前か。

 xenの場合はkmod-drbd83-xenというカーネルモジュールを入れる必要がある。
# yum remove kmod-drbd83
# yum install kmod-drbd83-xen
これでうまくいった。

ちなみに、上記手順でもサービス起動時にカーネルモジュールが読み込まれない場合は、以下のコマンドでカーネルモジュールの依存関係を更新してやる。
# depmod -a

2012年3月9日金曜日

CentOS 5.6でheartbeatとpacemakerのコンパイルエラー

LPIC304の勉強の一環で、Linuxのpacemaker + heartbeatを試すことに。
環境は以下の通り。
  • OS:CentOS 5.6
  • heartbeat-3.0.7
  • pacemaker-1.1.6-1
  • autoconf-2.68
  • automake-1.11
とりあえず公式HP を参考にソースコードからコンパイル。
すると以下のエラーが出た。
Making all in doc
gmake[1]: ディレクトリ `/root/src/Heartbeat-3-0-7e3a82377fa8/doc' に入ります
\
        --xinclude \
        http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl heartbeat.xml
gmake[1]: --xinclude: コマンドが見つかりませんでした
gmake[1]: *** [heartbeat.8] エラー 127
gmake[1]: ディレクトリ `/root/src/Heartbeat-3-0-7e3a82377fa8/doc' から出ます
make: *** [all-recursive] エラー 1
どうやらドキュメントの生成中に、xincludeというxml関連のコマンドが無くて失敗している模様。別にドキュメントなんていらないんだけど、迷惑な話だ。
調べていると、Linux-HA mailing list でも同じエラーが話題になっている。
どうやら、libxsltのRPMを入れればよいらしいので、yumでいれて問題解消。
その後./bootstrapからやり直したらうまくいった。(ちなみに、その後のmakeめちゃ長いです)


続いてpacemaker。公式HPの手順通り進めていくと、以下のエラーが出た

autoreconf: running: /usr/local/bin/autoconf --force --warnings=no-portability
configure.ac:86: error: possibly undefined macro: AC_LIBTOOL_DLOPEN
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
configure.ac:87: error: possibly undefined macro: AC_LIBLTDL_CONVENIENCE
configure.ac:88: error: possibly undefined macro: AC_PROG_LIBTOOL
autoreconf: /usr/local/bin/autoconf failed with exit status: 1
Now run ./configure
configure: error: cannot find install-sh, install.sh, or shtool in . "."/.
これはlibtoolのバージョンが古かったために発生したようで、最新のlibtool-2.4をソースから入れたら解消した。

続いてこんなエラー
configure: error: The libxslt developement headers were not found
これはヘッダファイルがないとのことなので、libxlst-develを入れればよさそうな気がする。yumで入れたら解消した。

さらにこんなエラー
./configure: line 16612: syntax error near unexpected token `libqb,'
./configure: line 16612: `PKG_CHECK_MODULES(libqb, libqb, HAVE_libqb=1, HAVE_libqb=0)'
調べていると、どうやらpkg-configが悪さをしているようだ。
PRMのバージョンを調べてみると、pkgconfig-0.21-2.el5であり、2006年ぐらいのもの。
autoconfやautomakeは最新のものをソースからコンパイルして入れているので、pkg-configだけ古いが悪かったようだ。
ココから最新のpkg-config-0.26のソースコードを落としてきて、インストール。
これでうまくいった。

つづいて、こんなエラー

configure: error: Package requirements (libcpg) were not met:

No package 'libcpg' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables cpg_CFLAGS
and cpg_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
PKG_CONFIG_PATHの環境変数が悪いかもとか言われているので、PKG_CONFIG_PATH=/usr/lib/pkgconfigと設定してみたが、効果なし。
完全に行き詰った。


もう最新のソースはあきらめて、RPMで入れることにした。。。
# rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm
# wget -O /etc/yum.repos.d/clusterlabs.repo  http://clusterlabs.org/rpm/epel-5/clusterlabs.repo
# yum install pacemaker.i386
嗚呼、なんて簡単なんだ。。。orz

2012年3月7日水曜日

keepalived 1.2.2とLVSの連携でハマった点

LPIC304の試験の勉強として、keepalivedとLVSを連携させてみようと試みたところ、いくつかはまったので書いておく。

環境は以下の通り。
  • OS : CentOS release 5.6 (Final)
  • Kernel : 2.6.18-238.el5xen
  • keepalived : 1.2.2
keepalivedのコンパイル中に変なことに気付いた。

# tar zxvf keepalived-1.2.2.tar.gz
# cd keepalived-1.2.2
# ./configure
(中略)
Keepalived configuration
------------------------
Keepalived version       : 1.2.2
Compiler                 : gcc
Compiler flags           : -g -O2 -DETHERTYPE_IPV6=0x86dd
Extra Lib                : -lpopt -lssl -lcrypto
Use IPVS Framework       : No ←★LVSとの連携ができていない
IPVS sync daemon support : No ←★
Use VRRP Framework       : Yes
Use Debug flags          : No
LVSは入っていて、動作確認までしていたのに、連携できないとはどういうことか!

調べていると、どうやらkernelのソースコードに入っているip_vs.hがないとだめのようだ。
そもそも、kernelのソースコードは入っていなかったのでyumでインストール。
# yum install kernel-devel
# find / -name ip_vs.h
/usr/src/kernels/2.6.18-274.18.1.el5-i686/include/net/ip_vs.h
これでip_vs.hが入れられたので、./configureのオプションに場所を教えてあげる。
# ./configure --with-kernel-dir=/usr/src/kernels/2.6.18-274.18.1.el5-i686
(中略)
Keepalived configuration
------------------------
Keepalived version       : 1.2.2
Compiler                 : gcc
Compiler flags           : -g -O2 -DETHERTYPE_IPV6=0x86dd
Extra Lib                : -lpopt -lssl -lcrypto
Use IPVS Framework       : Yes★←うまくいってます!
IPVS sync daemon support : Yes★←
IPVS use libnl           : No
Use VRRP Framework       : Yes
Use Debug flags          : No
うまくいった!つづいてmake
# make
が、そこで以下のようなエラー(一部略)
/usr/include/sys/types.h:62: error: conflicting types for ‘dev_t’
/usr/src/kernels/2.6.18-274.18.1.el5-i686/include/linux/types.h:22: error: previous declaration of ‘dev_t’ was here
/usr/include/sys/types.h:67: error: conflicting types for ‘gid_t’
/usr/src/kernels/2.6.18-274.18.1.el5-i686/include/linux/types.h:54: error: previous declaration of ‘gid_t’ was here
/usr/include/sys/types.h:72: error: conflicting types for ‘mode_t’
/usr/src/kernels/2.6.18-274.18.1.el5-i686/include/linux/types.h:24: error: previous declaration of ‘mode_t’ was here
/usr/include/sys/types.h:77: error: conflicting types for ‘nlink_t’
/usr/src/kernels/2.6.18-274.18.1.el5-i686/include/linux/types.h:25: error: previous declaration of ‘nlink_t’ was here
/usr/include/sys/types.h:82: error: conflicting types for ‘uid_t’
/usr/include/time.h:105: error: conflicting types for ‘timer_t’
/usr/include/sys/select.h:78: error: conflicting types for ‘fd_set’
/usr/include/sys/types.h:235: error: conflicting types for ‘blkcnt_t’
調べていると、keepalivedはkernelのバージョンによってコンパイルできないことがあるらしい。
参考にしたのはこちら

結局、最新の1.2.2ではなく、古い1.1系の最終版である1.1.20をつかうことに。
これはうまくいった。