どうも、プライベートも HA 構成したい かっぱ@inokara)です。

はじめに

01

至ってシンプルですね。

今回は lb-test01 と lb-test02 の部分の構築と Floting な EIP の付け替えを行ってみたいと思います。


Corosync と Pacemaker について

参考

以下の資料がとても解りやすいと思います。

Corosync

  • ノードの死活監視を行うソフトウェア
  • Totem Single Ring Ordering and Membership プロトコルを実装した高可用ソリューション
  • 今回は各ノードの死活監視を行い、ノードの異常を検知した場合には正常系のノードへの切り替えを行います

pacemaker

  • Heartbeat の後継
  • クラスタのリソース制御機能
  • Heartbeat 2.x のリソース制御部分が Pacemaker として切りだされた
  • Pacemaker 単体では動作しない為、Heartbeat や Corosync と組み合わせて利用する
  • 今回は各ノードの停止を検知して EIP の付け替えを行います

セットアップ

セットアップにあたって

Corosync と Pacemaker をセットアップしていきたいと思います。尚、順次インストールしていきたいところですが pacemaker のインストールに際して、依存関係で corosync 関連パッケージを事前にインストールしておく必要があります。

インストールする環境

  • Amazon Linux AMI 2014.03.2 (HVM)

注意点

  • Amazon Linux のリポジトリには pacemaker が存在しない( corosync とかはあるのに…)
  • ビルド後に pacemaker のインストールを行う

ハマったというかこれどうしようか問題

当初はこちらからダウンロードしたリポジトリパッケージを利用して以下のような手順でインストールを行いました。

cd /tmp
wget http://osdn.dl.sourceforge.jp/linux-ha/60151/pacemaker-1.0.13-1.2.el6.x86_64.repo.tar.gz
tar zxvf pacemaker-1.0.13-1.2.el6.x86_64.repo.tar.gz
sudo cp pacemaker-1.0.13-1.2.el6.x86_64.repo/pacemaker.repo /etc/yum.repos.d/
sudo yum install pacemaker

を実行すると…以下のような Perl の依存関係でインストールが難しい…。

02

そこで…環境に合わせてパッケージをビルドし直すことにします。

事前準備

依存関係を解消したパッケージを作成する為に各種の依存パッケージを事前にインストールします。

lm_sensors 関連パッケージのインストール
cd /tmp/
yum install dmidecode -y
wget ftp://rpmfind.net/linux/centos/6.5/os/x86_64/Packages/lm_sensors-devel-3.1.1-17.el6.x86_64.rpm
wget ftp://rpmfind.net/linux/centos/6.5/os/x86_64/Packages/lm_sensors-3.1.1-17.el6.x86_64.rpm
wget ftp://rpmfind.net/linux/centos/6.5/os/x86_64/Packages/lm_sensors-libs-3.1.1-17.el6.x86_64.rpm
rpm --test -Uvh lm_sensors-*
rpm -Uvh lm_sensors-*
pacemaker 関連パッケージのインストール
yum -y install 
make libuuid-devel ncurses-libs kernel-devel flex 
libtool-ltdl-devel libtool-ltdl libtool libcurl-devel git 
ncurses-devel openssl-devel libselinux-devel cluster-glue-libs-devel libesmtp-devel 
net-snmp-devel asciidoc help2man publican inkscape 
docbook-style-xsl corosync corosynclib-devel automake autoconf 
libtool-ltdl-devel pkgconfig python glib2-devel 
libxml2-devel libxslt-devel python-devel gcc-c++ bzip2-devel 
gnutls-devel pam-devel libqb-devel intltool swig 
heartbeat-devel heartbeat-libs heartbeat

corosync も合わせてインストールしてしまいます。

Pacemaker パッケージの再作成

SRPM で環境に応じたパッケージを再作成する。

wget http://jaist.dl.sourceforge.jp/linux-ha/60151/pacemaker-1.0.13-1.2.el6.srpm.tar.gz
tar zxvf pacemaker-1.0.13-1.2.el6.srpm.tar.gz
cd pacemaker-1.0.13-1.2.el6.srpm
rpmbuild --rebuild pacemaker-1.0.13-1.el6.src.rpm
# 必要に応じてインストールする
rpmbuild --rebuild pacemaker-mgmt-2.0.1-1.el6.src.rpm

Paceman パッケージのインストール

cd /root/rpmbuild/RPMS/x86_64
rpm --test -Uvh pacemaker-
rpm -Uvh pacemaker-*

インストールの確認を行います。

rpm -qa | egrep 'pacemaker|corosync'

以下のようにインストールされているパッケージが確認出来るかと思います。

03


設定

corosync の設定

/etc/corosync/corosync.conf.example.udpu を参考に以下のように corosync.conf を修正します。

# Please read the corosync.conf.5 manual page
compatibility: whitetank

service {
    name: pacemaker
    ver: 0
    use_mgmtd: yes
}

totem {
        version: 2
        secauth: off
        interface {
                member {
                        memberaddr: ${lb-test01_IP}
                }
                member {
                        memberaddr: ${lb-test02_IP}
                }
                ringnumber: 0
                # lb-test01 と lb-test02 でそれぞれ設定しましょう
                bindnetaddr: ${lb-test01_IP_network_address} or ${lb-test02_IP_network_address}
                mcastport: 5405
                ttl: 1
        }
        transport: udpu
}

logging {
        fileline: off
        to_logfile: yes
        to_syslog: yes
        debug: on
        logfile: /var/log/cluster/corosync.log
        debug: off
        timestamp: on
        logger_subsys {
                subsys: AMF
                debug: off
        }
}

bindnetaddr のみ各 LB が属しているネットワークアドレスを指定しましょう。尚、項目の詳細についてはこちらをご確認下さい。


corosync の起動

それぞれのノードで Corosync の設定が終わったら順次 Corosync を起動していきます。

/etc/init.d/corosync start

起動の確認

/etc/init.d/corosync status

以下のように corosync の稼働が確認出来ます。

04

クラスタの確認

クラスタが構成されているかは crm_mon コマンドを使って確認します。各ノードで crm_mon コマンドを実行している結果です。

05

ノード間の死活監視は出来ました!


Pacemaker を利用した EIP の入れ替え

ノード間の死活監視は出来るようになったので Pacemaker を使って EIP を入れ替えられるように設定してみたいと思います。

EIP を入れ替える為に…

ノードの死活によって EIP を入れ替える仕事をしてくれるのが Pacemaker となります。また、実際に入れ替えを行う為に以下のようなツールを使います。

イメージとしては Pacemaker がノードの死活を検知して上記のスクリプトを実行して EIP を付け替える感じです。

06

ざっくりとした処理の流れは上図の通りです。

設定

参考にさせて頂いたブログ記事ほぼそのままです。感謝です。

スクリプトを取得してインストールする
cd /root/
git clone https://github.com/moomindani/aws-eip-resource-agent.git
cd aws-eip-resource-agent
git checkout -b myeip
vi eip

以下のように修正します。

--- eip.original 2014-07-03 06:20:12.875197608 +0000
+++ eip       2014-07-03 05:21:51.025291086 +0000
@@ -82,7 +82,7 @@
     if [ $? =  $OCF_SUCCESS ]; then
        return $OCF_SUCCESS
     fi
-    /usr/bin/aws ec2 associate-address --public-ip ${OCF_RESKEY_elastic_ip} --instance-id ${instance_id}
+    /usr/bin/aws ec2 associate-address --allocation-id ${alloc_id} --network-interface-id ${interface_id}
 }

 eip_stop() {
@@ -106,6 +106,10 @@
 }

 instance_id=`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id`
+local_ip=`wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4`
+alloc_id=`/usr/bin/aws ec2 describe-addresses --public-ips ${OCF_RESKEY_elastic_ip} --query "Addresses[*].AllocationId" --output text`
+mac_addr=`/sbin/ip link show eth1 | tail -1 | awk '{print $2}'`
+interface_id=`wget -q -O - http://169.254.169.254/latest/meta-data/network/interfaces/macs/${mac_addr}/interface-id`

 case $__OCF_ACTION in
 meta-data)     meta_data

複数の NIC があった場合を想定してインターフェース毎に EIP を割り当てられるように修正しています。また、EIP の Allocation ID や NIC の Interface ID を取得する為に泥臭いことをやっているのが下の部分です。(この辺は要改善です。)修正したら、下記のようにスクリプトをインストールします。

mv eip /usr/lib/ocf/resource.d/heartbeat/
chown root:root /usr/lib/ocf/resource.d/heartbeat/eip
chmod 0755 /usr/lib/ocf/resource.d/heartbeat/eip

合わせてスクリプトには実行権限を付与します。

AWS の Credential 設定

上記のスクリプトは AWS CLI を実行しますので AWS の Credential の設定が必要になります。

aws configure

を実行します。実行後は以下の内容の ${USER}/.aws/config ファイルが作成されます。

[default]
aws_access_key_id=AKxxxxxxxxxxxxxxxxxx
aws_secret_access_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
region=us-east-1
Pacemaker の設定

Pacemaker の設定は crm コマンドから configure のサブコマンドからインタラクティブに設定も可能ですが、予め設定ファイルを作成しておいて load update を実行することで設定ファイルを読み込ませて設定を反映させることが可能です。

以下のような設定ファイルを作成します。

property 
    no-quorum-policy="ignore" 
    stonith-enabled="false" 
    crmd-transition-delay="0s"

primitive eip ocf:heartbeat:eip 
    params 
        elastic_ip="${EIP}" 
    op start   timeout="60s" interval="0s"  on-fail="stop" 
    op monitor timeout="60s" interval="10s" on-fail="restart" 
    op stop    timeout="60s" interval="0s"  on-fail="block"

${EIP} を適宜設定して適当なファイル名(今回は eip.crm )という名前で保存します。その後、以下のようにして設定を読み込ませます。

crm configure load update eip.crm
Corosync の設定追加

先ほど Corosync の設定を行う際には設定していなかった aisexec ディレクティブの設定を行います。

aisexec {
        user:        root
        group:       root
}

上記の設定を /etc/corosync/corosync.conf に追加します。追加後の corosync.conf は下記のこちらの通りとなります。

EIP の切り替えをやってみよー

正常な状態

lb-test01 がマスターノード、lb-test02 がバックアップノードとなります。

07

EIP は lb-test01 に着いている状態です。

平和です。

lb-test01 に障害!

lb-test01 の Corosync を停止…姉さん、事件です。

08

でも EIP は lb-test02 に切り替わりました。

lb-test01 が復旧!

lb-test01 はすぐに復旧して Corosync も復活しました。

09

但し、Corosync のマスターノードは lb-test02 の状態です。(このあたりの挙動は引き続き調査!)lb-test02 の Corosync を再起動すると lb-test01 がマスターノードに昇格します。


引き続き…

今回やったこと

  • Pacemaker と Corosync のセットアップを行いました
  • Corosync によるノードの死活監視を試しました
  • Pacemaker を利用してリソース(EIP)の切り替えを行いました

感じたこと

  • Amazon Linux にて Pacemaker のパッケージが含まれていなかったのがキツかった
  • EIP の切り替えスクリプトのブラッシュアップが必要!!

tips

UNCLEAN なノードが残ってしまった!

何らかの原因でクラスタ内のノードをクラスタから切り離した場合に UNCLEAN なノードがクラスタ内に残ってしまうことがあります。その際には crm コマンドの configure モードから edit を選択してノードの削除をしてしまいましょう。

crm

を実行すると以下のようにプロンプトが変わります。その後、configure と入力するとさらにプロンプトが変わります。

10

さらに edit を入力すると、クラスタの設定を修正することが可能です。(vi で開きます)

11

UNCLEAN なノードを削除して保存(:wp)します。最後に commit コマンドを発行して設定を反映させます。

12

/var/lib/heartbeat/crm/ 以下をまるっと削除

Corosync 絡みで何かあったら迷わず /var/lib/heartbeat/crm/ 以下を削除すると多少幸せにはなれる。

元記事は、こちら