Pacemaker+DRBD+heartbeatでMySQLのクラスタ

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 ]

になる。

これで準備はＯＫ。

設定
================

pacemakerの設定に入っていく。どちらかのノードで、crmのコマンドを実行し、設定ツールを起動。その後configureを入力し、設定モードへ。

    [root@db1 ~]# crm
    crm(live)# configure
    crm(live)configure#

この後は以下の順序で設定していく。

1. 全体の設定
2. 共有IPアドレスをリソースとして追加
3. DRBDをリソースとして追加
4. ファイルシステム(マウント定義)をリソースとして追加
5. MySQLをリソースとして追加
6. リソースのグループ、リソース間の制約・順序の設定

全体の設定
----------------

まず全体の設定は、以下コマンドをcrm(live)configure#のプロンプトに打ち込めばＯＫ。

    property $id="cib-bootstrap-options" no-quorum-policy="ignore" stonith-enabled="false"

no-quorum-policyは２台構成の場合は必ず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を切ればＯＫ

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

最後に、リソースのグループ、リソース間の制約・順序の設定する。

    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

設定の意味は、

    １行目は「ファイルシステムと共有IPとMySQLをグループ『mysql』に指定」
    ２行目は「mysqlグループとDRBDのマスターは同時に存在しなくてはならない」
    ３行目は「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/*