DRBDを用いたHAクラスタシステム
概要
CentOS6 + DRBD + Pacemaker + Corosync を利用してMySQLのHAクラスタシステムを構築します。
クラスタシステムを構成する各ソフトウェアについて
DRBD
DRBDはLinuxカーネルのブロックデバイスドライバのレイヤで動作するデータ冗長化ソフトウェアで、Distributed Replicated Block Deviceの略です。簡潔に言い表すと“ネットワークを介してHDD(パーティション)のミラーリングを行うソフトウェア”です。
多くの HAクラスタ環境では、クラスタのデータ領域に共有ストレージを用意するのが一般的ですが、DRBDを利用したHAクラスタ環境ではネットワークを使用したリアルタイムなデータ同期が可能となるため、共有ストレージを必要としません。
「シェアードナッシング」タイプのクラスタシステムを構築します。
コミュニティ版DRBDの入手先:
CentOS5まではCentOSのextraリポジトリにて入手可能でしたが、CentOS6からは入手不可となっています。コミュニティ版の推奨パッケージは以下のレポジトリから入手可能です。
Pacemaker
Pacemakerはクラスタリソースを管理するオープンソース・ソフトウェアです。
CRM(クラスタリソースマネージャ)とも呼ばれ、クラスタリソース(仮想IP、データベースなど)サービスの起動・停止や動作状態を監視します。
「Heartbeat」または「Corosync」とセットで動作します。
配布元:
CentOSのbaseリポジトリ
Linux-HA-Japanのレポジトリ
今回はLinux-HA-Japanのレポジトリを利用
Corosync
Corosyncはクラスタシステムを制御するためのオープンソース・ソフトウェアです。
クラスタシステムを構成するノードの死活監視を行います。
以前は、"DRBD + Pacemaker + Heartbeat"を組み合わせたクラスタシステムが多かったのですが、最近では Heartbeat に代わって Corosync が主流となっております。
各コミュニティの体制や、上記OSSのバージョンアップ等によって、パッケージの配布元や構築手順、設定方法などが微妙に変わっている事がよくあります。
以前に構築した際の手順を流用して構築を進めて行くとだいたいどこかでエラーが出力されたりしてうまくいかないことが少なくありません。
実は構築前に現時点における各パッケージのバージョン選定や最適な組み合わせの確認が、一番大変だったりします。。
組み合わせの検討を煩雑に感じておられる方や、自信の無い方は、弊社のDRBD構築支援サービスをご検討ください。
DRBDの開発元であるLINBIT社にてLinux カーネル毎にビルド、動作検証済みのパッケージがDRBDだけでなく、関連する Pacemaker や Corosync をも含んだ形で纏めて提供しております。
クラスタシステムを構成する各OSSがLINBIT社のレポジトリひとつで一括管理できるメリットがございます。また、導入後のサポート体制もございますのでより安心してご利用いただくことが可能です。
環境
OS | CentOS 6.6 |
DB | MySQL(CentOS 6.6バンドル版) |
冗長化 | drbd84-utils |
kmod-drbd84 | |
CRM | pacemaker-1.1.12 |
corosync-2.3.4 |
システム構成
名称・役割 | 稼働系 | 待機系 |
---|---|---|
ホスト名 | db1.example.jp | db2.example.jp |
VIP | 10.1.0.10/24 | |
eth0 | 10.1.0.11/24 | 10.1.0.12/24 |
eth1 | 10.1.1.1/24 | 10.1.1.2/24 |
eth2 | 10.1.2.1/24 | 10.1.2.2/24 |
デフォルトGW | 10.1.0.254 |
※eth1、eth2はハートビートライン。eth1はハートビート兼DRBDデータ同期用とします。
デバイス | マウントポイント | サイズ |
---|---|---|
/dev/sda1 | /boot | 512MB |
/dev/sda2 | / | 2048MB |
/dev/sda3 | swap | 512MB |
/dev/sda4 | (/data) | 残り※ |
※/dev/sda4(/data)はクラスタシステムのMySQLの共有データ領域(DRBDデバイス)として使用する想定です。
OSインストール時に /dev/sda4(/data)は作成せずに、領域を余らせておいて、OSインストール後に fdiskコマンドでパーティションを作成します。
事前準備/作業前提
OSインストール後は SELinux と iptables を無効にしておきます。
MySQLのデータ領域用にマウントポイント:/dataを作成しておきます。
MySQLを事前にインストールしておきます。
構築の流れ
- レポジトリ追加
- パッケージのインストール(稼働系/待機系共通)
- 自動起動設定(chkconfig)の調整
- DRBDの設定(稼働系/待機系共通)
- DRBDの初回同期
- MySQLの初期設定
- DRBDの動作確認
- Corosync の設定(稼働系/待機系共通)
- Corosync と Pacemaker の起動
- Pacemakerでクラスタリソースを定義
- クラスタ状態確認
- クラスタの切り替え確認
構築方法
[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 ]
技術情報
関連サービス
お気軽にお問い合わせください。応対時間 9:30-17:30 [ 土・日・祝日除く ]
お問い合わせ