ELBはオートスケールで可用性も高く、ミドルウェアの心配しないでいいので便利なのですが、IP固定できないなど課題があるのと、障害時の調査がブラックボックスすぎて大変なため、Pacemakerを利用して冗長化構成のLoadBalancerを構築してみました。
CDPで言うFloating IPになります。
CDP:Floating IPパターン - AWS-CloudDesignPattern
- 利用するEC2
- LB構築
- Pacemaker導入
- Pacemakerリソースエージェントデプロイ
- クラスタの構築
- Failover挙動確認
- (補足)Failover時の通知
- (補足)failcountをクリアしてもリソース移動できないとき
- (補足)pcsコマンドはタブ補完が効きます
- (補足)Clusterの削除
利用するEC2
OSはCentOS7で以下の2台のEC2インスタンスを起動します。
冗長化のためにAZは分けてあります。
役割 | ホスト名 |
---|---|
LB 1台目 | srv-lb01 |
LB 2台目 | srv-lb02 |
LB構築
それぞれのインスタンスでLB構築します。手順は以下の記事の通り。
Apacheのmod_proxy_hcheckを利用してロードバランサーを構築してみる - YOMON8.NET
Pacemaker導入
それぞれのEC2インスタンスでPacemakerをインストールします。
# 必要なパッケージのインストール yum install pacemaker corosync pcs # クラスタユーザのパスワード設定 passwd hacluster # pcs (pacemaker/corosync configuration system)サービスの起動有効化 systemctl start pcsd systemctl enable pcsd
awsコマンドも利用できるようにしておきます。IAMポリシーの例は以下の通り。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1480492145000", "Effect": "Allow", "Action": [ "ec2:AssociateAddress", "ec2:Describe*", "ec2:DisassociateAddress" ], "Resource": [ "*" ] } ] }
Pacemakerリソースエージェントデプロイ
こちらのリポジトリを使わせてもらっています。
GitHub - moomindani/aws-eip-resource-agent: Resource Agent for AWS EC2 EIP
VPCのEIPに対応させるためforkさせてもらって少し編集しました。これを両方のEC2インスタンスにデプロイします。
rm -fR /tmp/aws-eip-resource-agent cd /tmp git clone https://github.com/yomon8/aws-eip-resource-agent.git cd aws-eip-resource-agent git checkout develop 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
クラスタの構築
この項目の作業は片側のノード(例えばsrv-lb01
)のみで実行します。(両ノードでの実行は不要)
クラスタ設定
まずはクラスタを構築します。
# 任意のクラスタの名前 cluster_name=clustername # LoadBalancerに紐付けるEIP eip=52.198.xxx.xxx # 2台のEC2インスタンスのホスト名(ホスト名でアクセスできるようにしておきます) node1=srv-lb01 node2=srv-lb02 # haclusterユーザのパスワード password=p@ssw0rd # Clusterの初期設定 pcs cluster auth ${node1} ${node2} -u hacluster -p ${password} --force pcs cluster setup --name ${cluster_name} ${node1} ${node2} pcs cluster start --all # Clusterの詳細設定 pcs property set stonith-enabled=false pcs property set no-quorum-policy=ignore pcs property set crmd-transition-delay="0s" pcs resource defaults resource-stickiness="200" migration-threshold="2"
この時点でクラスタが登録できているはずです。pcs status
コマンドでエラーが無くクラスタが登録できていることを確認します。
# pcs status Cluster name: cluster_name Last updated: Wed Dec 7 22:52:23 2016 Last change: Wed Dec 7 22:52:21 2016 by hacluster via crmd on srv-lb01 Stack: corosync Current DC: srv-lb01 (version 1.1.13-10.el7_2.4-44eb2dd) - partition with quorum 2 nodes and 0 resources configured Online: [ srv-lb01 srv-lb02 ] Full list of resources: PCSD Status: srv-lb01: Online srv-lb02: Online Daemon Status: corosync: active/disabled pacemaker: active/disabled pcsd: active/enabled
クラスタリソースの登録
# LoadBalancerに紐付けるEIP eip=52.198.xxx.xxx # クラスタリソースの登録 # eipの付け替え、EIPの移動には10〜20秒程度かかります pcs resource create res-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" # HTTPDサービスの死活監視 pcs resource create res-httpd systemd:httpd \ params \ op monitor interval="5s" timeout="3s" # クラスタリソースのグループ化 pcs resource group add GP_LB res-eip res-httpd pcs constraint colocation add res-eip res-httpd
pcs status
コマンドでもう一度状況を確認してみます。
# pcs status Cluster name: clustername Last updated: Wed Dec 7 15:02:14 2016 Last change: Wed Dec 7 14:58:25 2016 by root via cibadmin on srv-lb01 Stack: corosync Current DC: srv-lb01 (version 1.1.13-10.el7_2.4-44eb2dd) - partition with quorum 2 nodes and 2 resources configured Online: [ srv-lb01 srv-lb02 ] Full list of resources: Resource Group: GP_LB res-eip (ocf::heartbeat:eip): Started srv-lb01 res-httpd (systemd:httpd): Started srv-lb01 PCSD Status: srv-lb01: Online srv-lb01: Online Daemon Status: corosync: active/disabled pacemaker: active/disabled pcsd: active/enabled
Failover挙動確認
リソースhttpdの停止
上記の設定ではクラスタの設定にmigration-threshold="2"
を入れているので、リソースのチェックに一回失敗した場合も、一度は再起動かけます。
※ ここからは、コンソール2つ上げて片方でcrm_mon
コマンドやwatch -n 3 pcs status
みたいなコマンドを起動しておくと動きがよく見えます。
httpdのリソースであるres-httpd
側の動きを見ています。httpdを停止してみます。
[srv-lb01] # systemctl stop httpd
srv-lb01
上で一度停止したhttpdのサービスが再起動されてきたはずです。そして、もう一度httpdを止めると srv-lb02
にリソースが移動するのが確認できると思います。
failcountの確認とリセット
migration-threshold="2"
と設定されているため、failcountが2回になるとフェールオーバーされます。failcount
は以下のコマンドで確認できます。
# pcs resource failcount show res-httpd Failcounts for res-httpd search-stress-test-lb02: 2
フェールバックする場合は、事前にfailcountをクリアしてあげる必要があります。
# pcs resource failcount reset res-httpd # pcs resource failcount show res-httpd No failcounts for res-httpd
(補足)Failover時の通知
Pacemakerでフェールオーバー時にAmazon SNSに通知するResource Agent書いてみた - YOMON8.NET
(補足)failcountをクリアしてもリソース移動できないとき
配置(location)の制約(constraint)が設定されてないでしょうか。
$ pcs constraint location show --full Location Constraints: Resource: GP_LB Disabled on: srv-lb01 (score:-INFINITY) (role: Started) (id:cli-ban-GP_LB-on-srv-lb01)
制約が設定されている場合は移動できないのでremoveしてあげます。
$ pcs constraint location remove cli-ban-GP_LB-on-srv-lb01
$ pcs constraint location show --full
Location Constraints:
(補足)pcsコマンドはタブ補完が効きます
pcs
コマンドは多機能でサブコマンドやオプションを覚えるの大変ですが、幸いタブ補完が効きます。
(補足)Clusterの削除
設定を最初からやり直したい場合は以下でClusterを破棄します。AMIで展開したい場合なども利用可能です。
pcs cluster destroy