DRBDを用いたHAクラスタシステム

概要

CentOS6 + DRBD + Pacemaker + Corosync を利用してMySQLのHAクラスタシステムを構築します。

クラスタシステムを構成する各ソフトウェアについて

DRBD

DRBDはLinuxカーネルのブロックデバイスドライバのレイヤで動作するデータ冗長化ソフトウェアで、Distributed Replicated Block Deviceの略です。簡潔に言い表すと“ネットワークを介してHDD(パーティション)のミラーリングを行うソフトウェア”です。

多くの HAクラスタ環境では、クラスタのデータ領域に共有ストレージを用意するのが一般的ですが、DRBDを利用したHAクラスタ環境ではネットワークを使用したリアルタイムなデータ同期が可能となるため、共有ストレージを必要としません。
「シェアードナッシング」タイプのクラスタシステムを構築します。

コミュニティ版DRBDの入手先:
CentOS5まではCentOSのextraリポジトリにて入手可能でしたが、CentOS6からは入手不可となっています。コミュニティ版の推奨パッケージは以下のレポジトリから入手可能です。

ELRepo.org

Pacemaker

Pacemakerはクラスタリソースを管理するオープンソース・ソフトウェアです。
CRM(クラスタリソースマネージャ)とも呼ばれ、クラスタリソース(仮想IP、データベースなど)サービスの起動・停止や動作状態を監視します。
「Heartbeat」または「Corosync」とセットで動作します。

配布元:
CentOSのbaseリポジトリ
Linux-HA-Japanのレポジトリ

今回はLinux-HA-Japanのレポジトリを利用

Corosync

Corosyncはクラスタシステムを制御するためのオープンソース・ソフトウェアです。
クラスタシステムを構成するノードの死活監視を行います。
以前は、"DRBD + Pacemaker + Heartbeat"を組み合わせたクラスタシステムが多かったのですが、最近では Heartbeat に代わって Corosync が主流となっております。

配布元:Linux-HA-Japanのレポジトリ

各コミュニティの体制や、上記OSSのバージョンアップ等によって、パッケージの配布元や構築手順、設定方法などが微妙に変わっている事がよくあります。
以前に構築した際の手順を流用して構築を進めて行くとだいたいどこかでエラーが出力されたりしてうまくいかないことが少なくありません。
実は構築前に現時点における各パッケージのバージョン選定や最適な組み合わせの確認が、一番大変だったりします。。

組み合わせの検討を煩雑に感じておられる方や、自信の無い方は、弊社のDRBD構築支援サービスをご検討ください。
DRBDの開発元であるLINBIT社にてLinux カーネル毎にビルド、動作検証済みのパッケージがDRBDだけでなく、関連する Pacemaker や Corosync をも含んだ形で纏めて提供しております。
クラスタシステムを構成する各OSSがLINBIT社のレポジトリひとつで一括管理できるメリットがございます。また、導入後のサポート体制もございますのでより安心してご利用いただくことが可能です。

環境

OSCentOS 6.6
DBMySQL(CentOS 6.6バンドル版)
冗長化drbd84-utils
kmod-drbd84
CRMpacemaker-1.1.12
corosync-2.3.4

システム構成

名称・役割稼働系待機系
ホスト名db1.example.jpdb2.example.jp
VIP10.1.0.10/24
eth010.1.0.11/2410.1.0.12/24
eth110.1.1.1/2410.1.1.2/24
eth210.1.2.1/2410.1.2.2/24
デフォルトGW10.1.0.254

※eth1、eth2はハートビートライン。eth1はハートビート兼DRBDデータ同期用とします。

デバイスマウントポイントサイズ
/dev/sda1/boot512MB
/dev/sda2/2048MB
/dev/sda3swap512MB
/dev/sda4(/data)残り※
ローカルストレージのパーティション

※/dev/sda4(/data)はクラスタシステムのMySQLの共有データ領域(DRBDデバイス)として使用する想定です。
OSインストール時に /dev/sda4(/data)は作成せずに、領域を余らせておいて、OSインストール後に fdiskコマンドでパーティションを作成します。

事前準備/作業前提

OSインストール後は SELinux と iptables を無効にしておきます。
MySQLのデータ領域用にマウントポイント:/dataを作成しておきます。
MySQLを事前にインストールしておきます。

構築の流れ

  1. レポジトリ追加
  2. パッケージのインストール(稼働系/待機系共通)
  3. 自動起動設定(chkconfig)の調整
  4. DRBDの設定(稼働系/待機系共通)
  5. DRBDの初回同期
  6. MySQLの初期設定
  7. DRBDの動作確認
  8. Corosync の設定(稼働系/待機系共通)
  9. Corosync と Pacemaker の起動
  10. Pacemakerでクラスタリソースを定義
  11. クラスタ状態確認
  12. クラスタの切り替え確認

構築方法

[1] レポジトリ追加

  • DRBDリポジトリ追加
# rpm -ivh http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm
  • Linux-HA-Japanレポジトリ(PacemakerとCorosync用)追加
# rpm -ivh http://iij.dl.sourceforge.jp/linux-ha/62369/pacemaker-repo-1.1.12-1.1.el6.x86_64.rpm
  • CentOS標準レポジトリ修正

CentOSのリポジトリに含まれるPacemakerとの衝突を避けるためCentOS標準のレポジトリを修正します。

# vi /etc/yum.repos.d/CentOS-Base.repo
exclude=pacemaker* corosync* heartbeat* resource-agents* cluster-glue* libqb*

[2] パッケージのインストール(稼働系/待機系共通)

  • DRBDインストール
# yum install drbd84* kmod-drbd84*
  • Pacemaker、Corosync などインストール
# yum install pacemaker-all

[3] 自動起動設定(chkconfig)の調整

各自動起動を設定します。

# chkconfig mysqld off
# chkconfig drbd on
# chkconfig corosync on
# chkconfig pacemaker on

[4] DRBDの設定(稼働系/待機系共通)

設定ファイルの存在を確認します。
DRBDの設定ファイルが置かれるディレクトリ構成です。

  • /etc/drbd.conf

/etc/drbd.d/配下のファイルをインクルードする設定が書かれています。
このファイルは初期状態(デフォルト)のままにしておきます。

include "drbd.d/global_common.conf";
include "drbd.d/*.res";
  • /etc/drbd.d/global_common.conf

全体的な設定を記載する設定ファイルですが、デフォルトのままで構いません。

  • DRBDリソースの設定

ファイル名は任意です。拡張子は㈰のインクルード設定に合わせて[.res]とします。
今回は「r0.res」という名前で設定ファイルを作成します。

# vi /etc/drbd.d/r0.res
resource r0 {
     protocol C;
     device /dev/drbd0;
     meta-disk internal;
     on db1 {
          address 10.1.1.1:7788;
          disk /dev/sda4;
     }
     on db2 {
          address 10.1.1.2:7788;
          disk /dev/sda4;
     }
}

[5] DRBDの初回同期

  • DRDB領域初期化
# drbdadm create-md r0
  • メタデータ書き込み

r0.res に定義したDRBD用のディスク(/dev/sda4)にメタデータを書き込みます。
OSインストール時にDRBD用のディスクパーティションを作成してしまった場合など、既に/dev/sda4にファイルシステムが構築されているので、メタデータの作成に失敗します。
以下のようにファイルシステムの先頭を壊してから再度初期化すれば成功するはずです。

# dd if=/dev/zero of=/dev/sda4 bs=512 count=1024
# drbdadm create-md r0
  • DRDB起動
# service drbd start
  • db1をDRBDプライマリに昇格
db1# drbdadm -- --overwrite-data-of-peer primary r0
  • DRBDの状態をモニタリング

初期同期中のため、相手側のステータスは"Inconsistent"と表示されます。
初期同期の進捗が%で表示されます。DRBD用の領域が大きい場合は、時間が掛かるため同期処理中に次の手順に進んで構いません。

db1# drbd-overview
(DRBDプライマリ側)
0:r0/0  SyncSource Primary/Secondary UpToDate/Inconsistent /data ext4 990M 1.3M 938M 1%
        [===============>....] sync'ed: 80.1% (209628/1046144)K

db2# drbd-overview
(DRBDセカンダリ側)
0:r0/0  SyncTarget Secondary/Primary Inconsistent/UpToDate
        [===============>....] sync'ed: 82.1% (191356/1046144)K

初期同期完了後のステータス
相手側のステータスが"UpToDate"と表示されます。

(DRBDプライマリ側)
0:r0/0  Connected Primary/Secondary UpToDate/UpToDate /data ext4 990M 1.3M 938M 1%

(DRBDセカンダリ側)
0:r0/0  Connected Secondary/Primary UpToDate/UpToDate
  • db1にてファイルシステム作成
db1# mkfs.ext4 /dev/drbd0

[6] MySQLの初期設定

  • マウントポイント確認

両ノードにマウントポイントが作成されていることを確認します。

# ls /data
  • db1にてDRBD領域をマウント
db1# mount /dev/drbd0 /data
db1# df -h

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       2.0G  1.3G  569M  70% /
tmpfs           499M     0  499M   0% /dev/shm
/dev/sda1       488M   27M  437M   6% /boot
/dev/drbd0      990M   23M  917M   3% /data
  • MySQLデータディレクトリ、シンボリックリンク作成

MySQLデータディレクトリをDRBD領域に作成します。
ローカル(/var/lib)のMySQLデータディレクトリはDRBD領域に作成したディレクトリのシンボリックリンクを作成します。

db1# mv /var/lib/mysql /data/
db1# ln -s /data/mysql /var/lib/mysql

db2# rm -fr /var/lib/mysql
db2# ln -s /data/mysql /var/lib/
  • db1 にてMySQL起動確認
db1# service mysqld start
  • MySQL停止

起動することが確認できたらMySQLを停止します。

db1# service mysqld stop
  • /dataをアンマウント
db1# umount /data

[7] DRBDの動作確認

  • db1のDRBDをセカンダリに降格
db1# drbdadm secondary r0
  • db2のDRBDをプライマリに昇格
db2# drbdadm primary r0
  • db2にてDRBD領域マウント
db2# mount /dev/drbd0 /data
  • db2にてMySQL起動確認
db2# service mysqld start
mysqld を起動中:      [  OK  ]
  • db2にてMySQL停止

db2側でもMySQLが起動することを確認できたらMySQLを停止します。

db2# service mysqld stop
  • /dataをアンマウント
db1# umount /data

[8] Corosync の設定(稼働系/待機系共通)

  • 設定ファイルの存在確認
# ls /etc/corosync
corosync.conf.example  corosync.conf.example.udpu  uidgid.d
  • サンプルファイルコピー

Corosyncの設定ファイルは"corosync.conf"です。
初期インストール時には存在しないので、サンプルファイルをコピーして設定ファイルを作成します。

# cd /etc/corosync
# cp -p corosync.conf.example corosync.conf
  • 設定ファイル編集

以下のサンプルを参考に環境に合わせてファイルの内容を編集します。

# vi corosync.conf 
totem { 
  version: 2 

  # crypto_cipher and crypto_hash: Used for mutual node authentication. 
  # If you choose to enable this, then do remember to create a shared 
  # secret with "corosync-keygen". 
  # enabling crypto_cipher, requires also enabling of crypto_hash. 
  crypto_cipher: none 
  crypto_hash: none 

  # interface: define at least one interface to communicate 
  # over. If you define more than one interface stanza, you must 
  # also set rrp_mode. 
  interface { 
    # Rings must be consecutively numbered, starting at 0. 
    ringnumber: 0 
    # This is normally the *network* address of the 
    # interface to bind to. This ensures that you can use 
    # identical instances of this configuration file 
    # across all your cluster nodes, without having to 
    # modify this option. 
    bindnetaddr: 10.1.1.0 
    # However, if you have multiple physical network 
    # interfaces configured for the same subnet, then the 
    # network address alone is not sufficient to identify 
    # the interface Corosync should bind to. In that case, 
    # configure the *host* address of the interface 
    # instead: 
    # bindnetaddr: 192.168.1.1 
    # When selecting a multicast address, consider RFC 
    # 2365 (which, among other things, specifies that 
    # 239.255.x.x addresses are left to the discretion of 
    # the network administrator). Do not reuse multicast 
    # addresses across multiple Corosync clusters sharing 
    # the same network. 
    mcastaddr: 239.255.1.1 
    # Corosync uses the port you specify here for UDP 
    # messaging, and also the immediately preceding 
    # port. Thus if you set this to 5405, Corosync sends 
    # messages over UDP ports 5405 and 5404. 
    mcastport: 5405 
    # Time-to-live for cluster communication packets. The 
    # number of hops (routers) that this ring will allow 
    # itself to pass. Note that multicast routing must be 
    # specifically enabled on most network routers. 
    ttl: 1 
  } 
  interface { 
    ringnumber: 1 
    bindnetaddr: 10.1.2.0 
    mcastaddr: 239.255.2.1 
    mcastport: 5405 
    ttl: 1 
  } 
  rrp_mode: active 
} 
logging { 
  # Log the source file and line where messages are being 
  # generated. When in doubt, leave off. Potentially useful for 
  # debugging. 
  fileline: off 
  # Log to standard error. When in doubt, set to no. Useful when 
  # running in the foreground (when invoking "corosync -f") 
  to_stderr: no 
  # Log to a log file. When set to "no", the "logfile" option 
  # must not be set. 
  to_logfile: yes 
  logfile: /var/log/cluster/corosync.log 
  # Log to the system log daemon. When in doubt, set to yes. 
  to_syslog: no 
  # Log debug messages (very verbose). When in doubt, leave off. 
  debug: off 
  # Log messages with time stamps. When in doubt, set to on 
  # (unless you are only logging to syslog, where double 
  # timestamps can be annoying). 
  timestamp: on 
  logger_subsys { 
    subsys: QUORUM 
    debug: off 
  } 
} 

quorum { 
  # Enable and configure quorum subsystem (default: off) 
  # see also corosync.conf.5 and votequorum.5 
  provider: corosync_votequorum 
  expected_votes: 2 
} 

nodelist { 
  node { 
    ring0_addr: 10.1.1.1 
    ring1_addr: 10.1.2.1 
    nodeid: 1 
  } 
  node { 
    ring0_addr: 10.1.1.2 
    ring1_addr: 10.1.2.2 
    nodeid: 2 
  } 
}

[9] Corosync と Pacemaker の起動

  • Corosync、Pacemaker起動
# service corosync start
# service pacemaker start
  • クラスタの状態をモニタリング
# crm_mon -i1 
Last updated: Wed Sep 9 18:15:19 2015 
Last change: Wed Sep 9 18:14:56 2015 
Stack: corosync 
Current DC: db2 (2) - partition with quorum 
Version: 1.1.12-561c4cf 
2 Nodes configured 
0 Resources configured 

Online: [ db1 db2 ] 

--- 
※[ctrl+c]キーでモニタリングを停止します。

クラスタリソースの設定はまだ何も行っていませんが、両ノードのステータスがOnlineであることが確認できます。

[10] Pacemakerでクラスタリソースを定義

  • crmコマンドで対話式にリソースを定義
# crm configure
crm(live)configure#
  • クラスタ全体設定
    ※stonithは無効、quorum-policyも無効に設定しています。
crm(live)configure# property stonith-enabled="false" ¥
no-quorum-policy="ignore"
  • リソース全体設定
    ※ resource-stickiness="INFINITY" はリソースのフェイルバックを無効に設定します。
    ※ migration-threshold=1 は failが1回発生するとリソースをフェイルオーバーします。
crm(live)configure# rsc_defaults rsc-options: ¥ 
  resource-stickiness="INFINITY" ¥ 
  migration-threshold=1
  • DRBDリソース定義
crm(live)configure# primitive res0_drbd_mysql ocf:linbit:drbd params drbd_resource="r0" ¥ 
  op start interval="0" timeout="240" ¥ 
  op stop interval="0" timeout="120"
  • ファイルシステム(マウント/アンマウント)リソース定義
crm(live)configure# primitive res0_fs_mysql ocf:heartbeat:Filesystem ¥ 
  params device="/dev/drbd0" directory="/data" fstype="ext4" ¥ 
  op start interval="0" timeout="60" ¥ 
  op stop interval="0" timeout="60" ¥ 
  op monitor interval="10" timeout="40"
  • VIPリソース定義
crm(live)configure# primitive res0_vip_mysql ocf:heartbeat:IPaddr2 ¥ 
  params ip="10.1.0.10" nic="eth0:1" cidr_netmask="24" ¥ 
  op monitor interval="10" timeout="30"
  • MySQLリソース定義
crm(live)configure# primitive res0_mysqld ocf:heartbeat:mysql ¥ 
  op start interval="0" timeout="120" ¥ 
  op stop interval="0" timeout="120" ¥ 
  op monitor interval="10" timeout="30"
  • MySQL、ファイルシステム、VIPリソース定義

MySQL、ファイルシステム、VIPリソースをひとつのリソースグループとして定義します。

crm(live)configure# group gr0_mysql res0_fs_mysql res0_vip_mysql res0_mysqld
  • DRBDリソース依存関係(プライマリ/セカンダリ)定義
crm(live)configure# ms ms_drbd_mysql res0_drbd_mysql ¥ 
  meta master-max="1" master-node-max="1" ¥ 
  clone-max="2" clone-node-max="1" notify="true"
  • 同居制約定義
crm(live)configure# colocation mysql_on_drbd inf: gr0_mysql ms_drbd_mysql:Master
  • 各リソース起動順序定義
crm(live)configure# order mysql_after_drbd inf: ms_drbd_mysql:promote gr0_mysql:start
  • 設定内容確認

showコマンドで設定した内容を確認します。

crm(live)configure# show

verifyコマンドで設定にエラーが無いことを確認します。

crm(live)configure# verify

commitコマンドで設定を反映します。

crm(live)configure# commit
  • 設定終了

exitコマンドでcrmコマンドから抜けます。

crm(live)configure# exit
bye

[11] クラスタ状態確認

  • クラスタ確認

どちらか一方のノードでクラスタの状態を確認します。

# crm_mon
Last updated: Wed Sep 9 18:39:19 2015 
Last change: Wed Sep 9 18:39:17 2015 
Stack: corosync 
Current DC: db2 (2) - partition with quorum 
Version: 1.1.12-561c4cf 
2 Nodes configured 
5 Resources configured 

Online: [ db1 db2 ] 

Resource Group: gr0_mysql 
  res0_fs_mysql (ocf::heartbeat:Filesystem): Started db1 
  res0_vip_mysql (ocf::heartbeat:IPaddr2): Started db1 
  res0_mysqld (ocf::heartbeat:mysql): Started db1 
Master/Slave Set: ms_drbd_mysql [res0_drbd_mysql] 
  Masters: [ db1 ] 
  Slaves: [ db2 ]

db1側でMySQLサービスが起動していることが確認できます。

[12] クラスタの切り替え確認

  • クラスタ状態モニタリング

どちらかのノードでクラスタの状態をモニタリングしておきます。

# crm_mon -i1 
Online: [ db1 db2 ] 

Resource Group: gr0_mysql 
  res0_fs_mysql (ocf::heartbeat:Filesystem): Started db1 
  res0_vip_mysql (ocf::heartbeat:IPaddr2): Started db1 
  res0_mysqld (ocf::heartbeat:mysql): Started db1 
Master/Slave Set: ms_drbd_mysql [res0_drbd_mysql] 
  Masters: [ db1 ] 
  Slaves: [ db2 ]
  • クラスタ切替

もう一方のノードでクラスタの切替えオペレーションを行います。
現在稼働系であるdb1をStanbdy状態に移行します。

# crm node standby db1

db1がstandby状態となり待機系であるdb2でリソースが稼働していることが確認できます。

# crm_mon -i1 
Node db1 (1): standby 
Online: [ db2 ] 

Resource Group: gr0_mysql 
  res0_fs_mysql (ocf::heartbeat:Filesystem): Started db2 
  res0_vip_mysql (ocf::heartbeat:IPaddr2): Started db2 
  res0_mysqld (ocf::heartbeat:mysql): Started db2 
Master/Slave Set: ms_drbd_mysql [res0_drbd_mysql] 
  Masters: [ db2 ] 
  Stopped: [ db1 ]

db1の状態をONLINEに戻しておきます。

# crm node online db1 

Online: [ db1 db2 ] 

Resource Group: gr0_mysql 
  res0_fs_mysql (ocf::heartbeat:Filesystem): Started db2 
  res0_vip_mysql (ocf::heartbeat:IPaddr2): Started db2 
  res0_mysqld (ocf::heartbeat:mysql): Started db2 
Master/Slave Set: ms_drbd_mysql [res0_drbd_mysql] 
  Masters: [ db2 ] 
  Slaves: [ db1 ]

技術情報

商標について

関連サービス

DRBD構築支援

お気軽にお問い合わせください。応対時間 9:30-17:30 [ 土・日・祝日除く ]

お問い合わせ
  • X