Pacemaker
2015/10/26更新
対応バージョン: Vagrant 1.4.3, Pacemaker 1.0.13, Heartbeat 3.0.5, Apache 2.2.15, Tomcat 7.0.56
以下で作成したApacheの2ノードクラスタにTomcatを組み込む手順を示す。
関連資料・記事
要件は以下の通りとする。
Tomcat用にVIP(192.168.1.102)を用意し、稼動系・待機系どちらにも接続できるようにする
コンテンツはSANやNASなどの共有領域には置かずに各サーバのローカルに置くものとする
待ち受けポートはデフォルトのままとし、Webサーバへのアクセスは8080、AJP接続は8009とする
Apacheに/app/でアクセスしてきた場合にVIPの8009ポートにAJP接続する
AJP接続がうまくいかない場合に備えてWebサーバ用のポート8080は閉じずに残しておく
Vagrantfile作成
基本的な設定は今までと同様とし、プロビジョニング用のスクリプトでTomcat環境を構築する。
# -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.define :s1 do |v| v.vm.box = "centos65_64" v.vm.hostname = "s1" v.vm.network :private_network, ip: "192.168.1.121" v.vm.network :private_network, ip: "192.168.9.121" v.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2122 v.vm.provision :shell, :path => "heartbeat.sh" v.vm.provision :shell, :path => "apache.sh" v.vm.provision :shell, :path => "tomcat.sh" v.vm.provision :shell, :path => "httpd-proxy.sh" end config.vm.define :s2 do |v| v.vm.box = "centos65_64" v.vm.hostname = "s2" v.vm.network :private_network, ip: "192.168.1.122" v.vm.network :private_network, ip: "192.168.9.122" v.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2222 v.vm.provision :shell, :path => "heartbeat.sh" v.vm.provision :shell, :path => "apache.sh" v.vm.provision :shell, :path => "tomcat.sh" v.vm.provision :shell, :path => "httpd-proxy.sh" v.vm.provision :shell, :path => "pacemaker.sh" end end
前回のheartbeat.shからApacheの環境構築部分を切り出してapache.shとし、Tomcatの構築(tomcat.sh)とAJP接続の設定(httpd-proxy.sh)をそれぞれ新規作成する。
pacemaker.shはtomcatのリソース定義を追加する。
heartbeat.sh, apache.sh
heartbeat.shの前回作成ファイルから以下のApacheの環境構築部分を削除してapache.shに移動する。
### install httpd(Apache) yum -y install httpd cp /vagrant/index.html /var/www/html
tomcat.sh
#!/bin/sh today=`date "+%Y%m%d"` ### install yum -y install java-1.7.0-openjdk useradd -s /sbin/nologin -u 700 tomcat cd /tmp wget http://ftp.riken.jp/net/apache/tomcat/tomcat-7/v7.0.56/bin/apache-tomcat-7.0.56.tar.gz tar zxvf apache-tomcat-7.0.56.tar.gz rm -f apache-tomcat-7.0.56.tar.gz mv apache-tomcat-7.0.56 /usr/local cd /usr/local chown -R tomcat:tomcat apache-tomcat-7.0.56 ln -s apache-tomcat-7.0.56 tomcat install -m 0755 /vagrant/tomcat /etc/init.d chkconfig --add tomcat chkconfig tomcat off ### setting cp -p /etc/profile /etc/profile.${today} JAVA_PATH=`readlink -e $(which java)` cat << EOD >> /etc/profile JAVA_HOME=${JAVA_PATH} CATALINA_HOME=/usr/local/tomcat export JAVA_HOME CATALINA_HOME EOD source /etc/profile ### firewall cd /etc/sysconfig cp -p iptables iptables.${today} iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 8009 -j ACCEPT service iptables save service iptables restart
### install
Tomcatに先立ちOpenJDKをインストールする。
実行ユーザのtomcatを作成する2台のサーバでそれぞれ作成するが、UIDの付与をシステムに任せておくと2台で別々のUIDが割り当てられる可能性があるので-uオプションでUIDを指定しておく。今回の構成のようにコンテンツが各ローカルにあれば問題ないが、共有領域に両サーバからアクセスする構成にする場合にUIDが異なっているとファイルの書き込みができなくなる。
Tomcatのバイナリを任意のミラーサイトからダウンロードして/usr/local配下に配置する。
/vagrantに用意した起動スクリプトtomcatを/etc/init.dにインストールし、システム起動時の自動起動はOFFにする。
(tomcat)
#!/bin/bash # # tomcat Startup script for the Tomcat Servlet Container # # chkconfig: 2345 35 65 # description: Tomcat is the servlet container that is used in the official \ # Reference Implementation for the Java Servlet and JavaServer \ # Pages technologies TOMCAT_USER=tomcat CATALINA_HOME=/usr/local/tomcat . /etc/rc.d/init.d/functions prog=tomcat start() { echo -n $"Starting $prog: " daemon --user $TOMCAT_USER $CATALINA_HOME/bin/startup.sh > /dev/null RETVAL=$? if [ $RETVAL -eq 0 ]; then echo_success else echo_failure fi echo [ $RETVAL = 0 ] && touch /var/lock/subsys/$prog return $RETVAL } stop() { echo -n $"Stopping $prog: " daemon --user $TOMCAT_USER $CATALINA_HOME/bin/shutdown.sh > /dev/null RETVAL=$? if [ $RETVAL -eq 0 ]; then echo_success else echo_failure fi echo [ $RETVAL = 0 ] && rm -f /var/lock/subsys/$prog return $RETVAL } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) INSTANCES=`ps --columns 512 -aef|grep java|grep tomcat|grep org.apache.catalina.startup.Bootstrap|wc -l` if [ $INSTANCES -eq 0 ]; then echo $prog is stopped RETVAL=3 else if [ $INSTANCES -eq 1 ]; then echo $prog is running 1 instance... else echo $prog is running $INSTANCES instances... fi RETVAL=0 fi ;; *) echo $"Usage: $prog {start|stop|restart|status|help}" exit 1 esac exit $RETVAL
### setting
/etc/profileにTomcatが動作するための環境変数JAVA_HOME,CATALINA_HOMEを定義する。
### firewall
2つの待受ポート(8080,8009)へのアクセスを許可する。
httpd-proxy.sh
### connect Apache - Tomcat cp /vagrant/httpd-proxy.conf /etc/httpd/conf.d/
### connect Apache - Tomcat
/vagrantに用意したApache - TomcatのAJP接続用のファイルを配置する。
(httpd-proxy.conf)
<Location /app/> ProxyPass ajp://192.168.1.102:8009/ </Location>
pacemaker.sh
前回の設定にTomcatのリソース定義を追加する。
: ### setting resouce - Tomcat JAVA_PATH="/usr" crm configure primitive vip_tomcat ocf:heartbeat:IPaddr2 params \ ip="192.168.1.102" nic="eth1" cidr_netmask="24" op monitor interval="10" crm configure primitive tomcat ocf:heartbeat:tomcat params \ java_home="${JAVA_PATH}" catalina_home="/usr/local/tomcat" \ tomcat_user="tomcat" statusurl="http://192.168.1.102:8080/" \ op start interval="0" timeout="90" on-fail="restart" \ op monitor interval="10" timeout="60" on-fail="restart" \ op stop interval="0" timeout="300" on-fail="block" crm configure group webapp vip_tomcat tomcat
### setting resouce - Tomcat
java_homeに指定するのはjavaプログラムそのものではなく2つ上のディレクトリ。RA(/usr/lib/ocf/resource.d/heartbeat/tomcat)の中でjavaのパスを以下のように決めているので注意が必要である。
(tomcat)
: 586 JAVA_HOME="${OCF_RESKEY_java_home}" : 644 JAVA=${JAVA_HOME}/bin/java :
仮想マシン起動
以上の設定が終わったら仮想マシンを起動し、以下のURLにアクセスしてどちらもTomcatのトップ画面が出ればOKである。
http://192.168.1.102:8080/ ... TomcatのWebサーバ
http://192.168.1.101/app/ .... Apache - Tomcat AJP接続

リソースの状態は以下のようになっているはずである。
# crm_mon -f : Online: [ s1 s2 ] Resource Group: web vip_httpd (ocf::heartbeat:IPaddr2): Started s1 httpd (ocf::heartbeat:apache): Started s1 Resource Group: webapp vip_tomcat (ocf::heartbeat:IPaddr2): Started s1 tomcat (ocf::heartbeat:tomcat): Started s1 Migration summary: * Node s1: * Node s2:
2015/10/07更新
対応バージョン: Vagrant 1.4.3, Pacemaker 1.0.13, Heartbeat 3.0.5
Vagrantで用意したCentOSのBOXを使って2つの仮想マシン上にPacemaker + Heartbeatによる2ノードクラスタを構築する手順を示す。ホストOSはUbuntu14.04。
関連資料・記事
[Vagrant] Vagrantインストール手順(VirtualBox環境) ... Ubuntu編
[Pacemaker] Pacemaker + Heartbeatによる2ノードクラスタ設定(Apache, Samba)
クラスタ環境は上記で作成した構成を踏襲するが、以下の点が異なっている。
NICのインタフェース名
eth1: サービス提供用(上記資料ではem1)
eth2: インターコネクト(上記資料ではp4p1)
リソース管理するサービスはApacheのみ(上記資料ではApacheとSamba)
rsyslogの設定は変更しない
仮想マシン作成
まず2台の仮想マシンを作成する。
% cd % mkdir -p vagrant/centos65 % cd vagrant/centos65 % vagrant init centos65_64 % ls Vagrantfile
各仮想マシンの設定が異なるのでVagrantfileを以下のように記述する。
# -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.define :s1 do |v| v.vm.box = "centos65_64" v.vm.hostname = "s1" v.vm.network :private_network, ip: "192.168.1.121" v.vm.network :private_network, ip: "192.168.9.121" v.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2122 v.vm.provision :shell, :path => "heartbeat.sh" end config.vm.define :s2 do |v| v.vm.box = "centos65_64" v.vm.hostname = "s2" v.vm.network :private_network, ip: "192.168.1.122" v.vm.network :private_network, ip: "192.168.9.122" v.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2222 v.vm.provision :shell, :path => "heartbeat.sh" v.vm.provision :shell, :path => "pacemaker.sh" end end
初回起動時のプロビジョニングとして各仮想マシンでHeatbeatの設定を行い(heartbeat.sh)、2台がHA構成になったあと2台目の仮想マシンでPacemakerの設定を行う(pacemaker.sh)。
heartbeat.shとpacemaker.shはそれぞれ以下のように記述し、Vagrantfileと同じパスに格納する。説明は後述する。
heartbeat.sh
#!/bin/sh yum update yum -y install wget ### install pacemaker cd /tmp tar xvzf /vagrant/pacemaker-1.0.13-2.1.el6.x86_64.repo.tar.gz cd pacemaker-1.0.13-2.1.el6.x86_64.repo yum -y -c pacemaker.repo install pacemaker-1.0.13-2.el6.x86_64 heartbeat-3.0.5-1.1.el6.x86_64 pm_extras-1.5-1.el6.x86_64 ### install httpd(Apache) yum -y install httpd cp /vagrant/index.html /var/www/html ### add iptables iptables -A INPUT -p udp -m udp --dport 694 -j ACCEPT service iptables save ### add hosts cat /vagrant/hosts_add >> /etc/hosts ### setting heartbeat install /vagrant/ha.cf /etc/ha.d install -m 0600 /vagrant/authkeys /etc/ha.d ### start heartbeat service heartbeat start
### install pacemaker
ホストOS側の共有ディレクトリ(Vagrantfileと同じパス)に格納したPacemakerのバイナリを展開してインストールする。
Pacemakerのバイナリは以下から入手できる。
http://sourceforge.jp/projects/linux-ha/releases/
### install httpd(Apache)
Apacheをインストールする。設定はとりあえずデフォルトのまま。
Apacheの動作をモニタするために内部的にwgetでHTTPアクセスをするのでwgetもインストールしておく。
また上記アクセスにおいてHTMLファイルにアクセスできる必要があるので以下のダミーHTMLを共有ディレクトリ(Vagrantfileと同じパス)に用意しておきApacheのドキュメントルートにコピーする。
(index.html)
<html> </html>
これをやっておかないとApacheのリソースが起動してもすぐ終了してしまう。
関連資料・記事
### add iptables
インターコネクト通信用ポート(694/udp)の接続を許可する。
### add hosts
サーバ2台分のホスト情報を追加する。
このファイルもダミーHTML同様、共有ディレクトリに用意しておく。
(hosts_add)
192.168.1.121 s1 192.168.1.122 s2
### setting heartbeat
Heartbeat用の設定ファイル(/etc/ha.d/ha.cf、/etc/ha.d/authkeys)を用意する。
このファイルも共有ディレクトリに用意しておく。
(ha.cf)
pacemaker on debug 0 udpport 694 keepalive 2 warntime 7 deadtime 10 initdead 10 logfacility local1 ucast eth2 192.168.9.121 ucast eth2 192.168.9.122 ping 192.168.1.1 node s1 node s2 watchdog /dev/watchdog respawn root /usr/lib64/heartbeat/ifcheckd
(authkeys)
auth 1 1 sha1 xxxxx <--- インターコネクト通信用の任意のパスフレーズ
### start heartbeat
heartbeatのサービスを起動する。
pacemaker.sh
#!/bin/sh ### wait for being ready cluster while [ 1 ] do crm node status > /dev/null 2>&1 if [ $? -eq 0 ]; then break fi sleep 1 done sleep 5 ### setting option crm configure property stonith-enabled="false" crm configure property no-quorum-policy="ignore" ### setting resouce crm configure primitive vip_httpd ocf:heartbeat:IPaddr2 params \ ip="192.168.1.101" nic="eth1" cidr_netmask="24" op monitor interval="10" crm configure primitive httpd ocf:heartbeat:apache params \ configfile="/etc/httpd/conf/httpd.conf" statusurl="http://192.168.1.101/" \ op start interval="0" timeout="90" on-fail="restart" \ op monitor interval="10" timeout="60" on-fail="restart" \ op stop interval="0" timeout="300" on-fail="block" ### grouping crm configure group web vip_httpd httpd
### wait for being ready cluster
クラスタが動作可能になってリソース制御ができるようになるまで待つ。
### setting option
各種オプションを設定する。
### setting resouce
リソースとしてVIP(vip_httpd)とApache(httpd)を定義する。
### grouping
上記で定義したリソースをグルーピングして一つのリソースグループとする。
仮想マシン起動
以上の設定が終わったら仮想マシンを起動する。
% vagrant up Bringing machine 's1' up with 'virtualbox' provider... Bringing machine 's2' up with 'virtualbox' provider... [s1] Importing base box 'centos65_64'... [s1] Matching MAC address for NAT networking... [s1] Setting the name of the VM... [s1] Clearing any previously set forwarded ports... [s1] Clearing any previously set network interfaces... [s1] Preparing network interfaces based on configuration... [s1] Forwarding ports... [s1] -- 22 => 2122 (adapter 1) [s1] Booting VM... [s1] Waiting for machine to boot. This may take a few minutes... [s1] Machine booted and ready! [s1] Setting hostname... [s1] Configuring and enabling network interfaces... [s1] Mounting shared folders... [s1] -- /vagrant [s1] Running provisioner: shell... [s1] Running: /tmp/vagrant-shell20141007-20822-ag7wdv Loaded plugins: fastestmirror : (ここからs1のプロビジョニング) : Starting High-Availability services: Done. [s2] Importing base box 'centos65_64'... [s2] Matching MAC address for NAT networking... [s2] Setting the name of the VM... [s2] Clearing any previously set forwarded ports... [s2] Clearing any previously set network interfaces... [s2] Preparing network interfaces based on configuration... [s2] Forwarding ports... [s2] -- 22 => 2222 (adapter 1) [s2] Booting VM... [s2] Waiting for machine to boot. This may take a few minutes... [s2] Machine booted and ready! [s2] Setting hostname... [s2] Configuring and enabling network interfaces... [s2] Mounting shared folders... [s2] -- /vagrant [s2] Running provisioner: shell... [s2] Running: /tmp/vagrant-shell20141007-20822-1pyt36a Loaded plugins: fastestmirror : (ここからs2のプロビジョニング) : Starting High-Availability services: Done. [s2] Running provisioner: shell... [s2] Running: /tmp/vagrant-shell20141007-20822-12eoo2m
初回起動時のみheartbeat.sh及びpacemaker.shが動き(プロビジョニング)、各種ソフトウェアのインストールと設定が行われる。
試しにs1(サーバ1)に接続してcrm_monを実行すると各ノードとリソースが正常に動作しているのが確認できる。この状態でhttp://192.168.1.101/にアクセスするとApacheのテスト画面が表示される。
% vagrant ssh s1 [vagrant@s1 ~]$ sudo crm_mon -A ============ Last updated: Mon Oct 6 17:36:38 2014 Stack: Heartbeat Current DC: s1 (0ae70a20-2a06-4775-98d8-4e6cdddfb170) - partition with quorum Version: 1.0.13-a83fae5 2 Nodes configured, unknown expected votes 1 Resources configured. ============ Online: [ s1 s2 ] Resource Group: web vip_httpd (ocf::heartbeat:IPaddr2): Started s1 httpd (ocf::heartbeat:apache): Started s1 Node Attributes: * Node s1: + s2-eth2 : up * Node s2: + s1-eth2 : up
このプロビジョニングは初回起動時だけ動作すればいいので2回目以降は動かない。
もしスクリプトに変更を加えたい時などは以下のようにいったん仮想マシンを削除して再作成すればよい。
% vagrant destroy Are you sure you want to destroy the 's2' VM? [y/N] y [s2] Forcing shutdown of VM... [s2] Destroying VM and associated drives... [s2] Running cleanup tasks for 'shell' provisioner... Are you sure you want to destroy the 's1' VM? [y/N] y [s1] Forcing shutdown of VM... [s1] Destroying VM and associated drives... [s1] Running cleanup tasks for 'shell' provisioner... % vagrant up :
2013/12/4更新
対応バージョン: Pacemaker 1.0.13, Heartbeat 3.0.5
Pacemaker + Heartbeatを使って2ノードのクラスタを構築する手順を示す。導入OSはCentOS 6.4。
PacemakerとHeartbeatはそれぞれ以下の役割を担い、協調して動作する。
Pacemaker
仮想IP、ApacheやMySQL等といった各種サービスをリソースとして扱い、起動/停止、動作状態の監視を行う。何らかの異常を検知すると自動的に再起動やフェールオーバなどの制御を行う。
Heartbeat
メンバーノードをクラスタとして動作させる。電源不良やKernel Panicといった低レイヤに関する障害が発生した場合にノードの切り離しや再起動などの制御を行う。
構築環境
ここでは以下の環境を構築する。
提供サービス
Apache
Samba
片系のノードで両サービスを提供し、障害時やメンテナンス時はサービス単位で停止/起動・フェールオーバ可能とする。
ノード
サーバ1: s1 (em1: 192.168.1.121, p4p1: 192.168.9.121)
サーバ2: s2 (em1: 192.168.1.122, p4p1: 192.168.9.122)
・em1: サービス提供用
・p4p1: インターコネクト(ハートビート)用
GWは192.168.1.1とする。
仮想IP
Apache用: 192.168.1.101
Samba用: 192.168.1.100
以降の設定にあたっては、クラスタが構築し終わるまではそれぞれのノードで同じ作業を行う。
インターコネクト用NIC設定
em1用の設定をコピーしてインターコネクト用NICの設定を行う。
# cd /etc/sysconfig/network-scripts # cp ifcfg-em1 ifcfg-p4p1 # vi ifcfg-p4p1
以下を削除
GATEWAY=192.168.1.1 DNS1=xxx.xxx.xxx.xxx DEFROUTE=yes
以下を変更
DEVICE=p4p1 HWADDR=xx:xx:xx:xx:xx:xx IPADDR=192.168.9.xxx
networkサービス再起動
# service network restart
相手のインターコネクト用NICが見えることを確認
# ping 192.168.9.xxx
Pacemaker, Heartbeatインストール
Linux-HA Japanよりパッケージを取得してインストールする。
http://sourceforge.jp/projects/linux-ha/releases/
pacemaker-1.0.13-1.1.el6.x86_64.repo.tar.gz (64bit用)
pacemaker-1.0.13-1.1.el6.i686.repo.tar.gz (32bit用)
ここでは64bit用をインストールする。
# tar xvzf pacemaker-1.0.13-1.1.el6.x86_64.repo.tar.gz # mv pacemaker-1.0.13-1.1.el6.x86_64.repo /tmp # cd /tmp/pacemaker-1.0.13-1.1.el6.x86_64.repo # yum -c pacemaker.repo install pacemaker-1.0.13-1.el6.x86_64 heartbeat-3.0.5-1.1.el6.x86_64 pm_extras-1.3-1.el6.x86_64 # yum list installed | grep pacemaker cluster-glue.x86_64 1.0.11-1.el6 @pacemaker 1.0.11-1.el6 @pacemaker corosync.x86_64 1.4.5-1.el6 @pacemaker corosynclib.x86_64 1.4.5-1.el6 @pacemaker heartbeat.x86_64 3.0.5-1.1.el6 @pacemaker heartbeat-libs.x86_64 3.0.5-1.1.el6 @pacemaker libesmtp.x86_64 1.0.4-16.el6 @pacemaker pacemaker.x86_64 1.0.13-1.el6 @pacemaker pacemaker-libs.x86_64 1.0.13-1.el6 @pacemaker pm_extras.x86_64 1.3-1.el6 @pacemaker resource-agents.x86_64 3.9.5-1.el6 @pacemaker
(*) pm_extrasをインストールするとインターコネクトLAN故障が標準ツールで見えるようになる。
ファイアウォール設定
インターコネクト通信用に694/udpを許可する。
# cd /etc/sysconfig # vi iptables
以下の行を追加
-A INPUT -p udp -m udp --dport 694 -j ACCEPT
iptables再起動
# service iptables restart
Heartbeat設定
まず低レイヤを制御するHeartbeatを設定する。
# vi /etc/ha.d/ha.cf pacemaker on debug 0 udpport 694 keepalive 2 warntime 7 deadtime 10 initdead 10 logfacility local1 ucast p4p1 192.168.9.121 ucast p4p1 192.168.9.122 ping 192.168.1.1 node s1 node s2 watchdog /dev/watchdog respawn root /usr/lib64/heartbeat/ifcheckd
以下、主なパラメータについて説明する。
pacemaker
リソース制御にPacemakerを使用するかどうか
udpport
インターコネクト通信で使用するudpポート
keepalive
インターコネクト通信の送信間隔(秒)
warntime
deadtime
インターコネクト通信途絶後に警告(warn)あるいは故障(dead)と判断するまでの時間(秒)
initdead
初期起動時に他のサーバの起動を待つ時間(秒)
logfacility
syslogのファシリティ
ucast
インターコネクト通信に使用するデバイスとIPアドレスの指定
ping
ネットワーク監視用に各ノードからpingを送信するIPアドレス。一般的にはルータなどを指定する。
node
クラスタに参加するノード名
watchdog
kernel提供のsoftdogデバイス名
respawn
起動するサブプロセスの指定
(*) respawnで指定しているifcheckdはpm_extrasに含まれるLinux-HA Japanオリジナルパッケージで、これを使うとインターコネクト通信が正常かどうかを見えるようになる。
続いて各ノードがクラスタメンバーとして動作できるように認証ファイルを配置する。
# vi /etc/ha.d/authkeys auth 1 1 sha1 xxxxxxxx ← 任意のパスフレーズ # chmod 0600 /etc/ha.d/authkeys
またPacemakerはログ量が多いので、必須ではないが別ファイルに切り出したほうがよい。
# cd /etc # cp -p rsyslog.conf rsyslog.conf.org # vi rsyslog.conf : local1.* /var/log/ha-log
(*) syslogのファシリティは前述のha.cfで変更可能
syslog再起動
# service rsyslog restart
Heartbeat起動
これでクラスタ化の準備ができたのでメンバーノード毎にHeartbeatを起動していく。
まずサーバ1(s1)。
# service heartbeat start # crm_mon -A ============ Last updated: Fri Sep 6 21:26:14 2013 Stack: Heartbeat Current DC: s1 (655c8a37-f03a-4b07-bece-d32b39adc80a) - partition with quorum Version: 1.0.13-30bb726 1 Nodes configured, unknown expected votes 0 Resources configured. ============ Online: [ s1 ] Node Attributes: * Node s1:
サーバ1がオンラインになるので別ターミナルを開いてサーバ2(s2)でもHeartbeatを起動する。
# service heartbeat start
これによりサーバ1,2ともオンラインになる。
# crm_mon -A ============ Last updated: Tue Sep 10 21:10:29 2013 Stack: Heartbeat Current DC: s1 (b7cf0247-85a1-472a-8430-fb38728488fd) - partition with quorum Version: 1.0.13-30bb726 2 Nodes configured, unknown expected votes 0 Resources configured. ============ Online: [ s1 s2 ] Node Attributes: * Node s1: + s2-p4p1 : up * Node s2: + s1-p4p1 : up
STONITH機能無効化
STONITHとは「Shoot The Other Node In The Head」の略で、相手ノードが不安定になった時にそのノードをOSごと再起動/停止する機能である。
この機能はデフォルトで有効になっているが、リソースを何も設定しない現状では以下のエラーになる。
# crm_verify -LV crm_verify[24723]: 2013/09/09_21:39:21 ERROR: unpack_resources: Resource start-up disabled since no STONITH resources have been defined crm_verify[24723]: 2013/09/09_21:39:21 ERROR: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option crm_verify[24723]: 2013/09/09_21:39:21 ERROR: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity Errors found during check: config not valid
そこでひとまず無効にしておく。
既にクラスタが構成されているので設定変更は任意のノードで1回だけ実行すれば自動的にメンバーノードに反映される。
# crm configure show node $id="b7cf0247-85a1-472a-8430-fb38728488fd" s1 node $id="e959ca5c-76e4-43c4-8641-6c6c71ac8fbc" s2 property $id="cib-bootstrap-options" \ dc-version="1.0.13-30bb726" \ cluster-infrastructure="Heartbeat" # crm configure property stonith-enabled="false" # crm_verify -LV (エラーなし) # crm configure show node $id="b7cf0247-85a1-472a-8430-fb38728488fd" s1 node $id="e959ca5c-76e4-43c4-8641-6c6c71ac8fbc" s2 property $id="cib-bootstrap-options" \ dc-version="1.0.13-30bb726" \ cluster-infrastructure="Heartbeat" \ stonith-enabled="false"
また、メンバーノードが2台の場合はquorumによる管理が不要になるのでcrm_attribute(*)をあわせて無効にしておく。
(*) クラスタに参加するメンバーノードが過半数に満たない場合の動作ポリシー
# crm configure property no-quorum-policy="ignore"
Pacemaker設定
Heartbeatの設定が終わったら次はPacemakerでリソースの定義を行う。
まずサービス提供用の仮想IPを定義する。
RA(Resource Agent)としてIPaddr2を使用し、以下のパラメータを設定する。
ip
仮想IPアドレス
nic
使用NIC
cidr_netmask
ネットマスク
# crm configure primitive vip_httpd ocf:heartbeat:IPaddr2 params \ ip="192.168.1.101" nic="em1" cidr_netmask="24" op monitor interval="10s" # crm configure primitive vip_samba ocf:heartbeat:IPaddr2 params \ ip="192.168.1.100" nic="em1" cidr_netmask="24" op monitor interval="10s"
リソースを定義するとすぐ有効になる。
# crm configure show vip_httpd primitive vip_httpd ocf:heartbeat:IPaddr2 \ params ip="192.168.1.101" nic="em1" cidr_netmask="24" \ op monitor interval="10s" \ meta target-role="Started" # crm configure show vip_samba primitive vip_samba ocf:heartbeat:IPaddr2 \ params ip="192.168.1.100" nic="em1" cidr_netmask="24" \ op monitor interval="10s" # crm_mon -A ============ Last updated: Tue Sep 10 22:19:44 2013 Stack: Heartbeat Current DC: s1 (b7cf0247-85a1-472a-8430-fb38728488fd) - partition with quorum Version: 1.0.13-30bb726 2 Nodes configured, unknown expected votes 1 Resources configured. ============ Online: [ s1 s2 ] vip_httpd (ocf::heartbeat:IPaddr2): Started s1 vip_samba (ocf::heartbeat:IPaddr2): Started s1 Node Attributes: * Node s1: + s2-p4p1 : up * Node s2: + s1-p4p1 : up
仮想IPが使えるようになっていることをpingで確認する。
# ping 192.168.1.101 PING 192.168.1.101 (192.168.1.101) 56(84) bytes of data. 64 bytes from 192.168.1.101: icmp_seq=1 ttl=64 time=0.404 ms 64 bytes from 192.168.1.101: icmp_seq=2 ttl=64 time=0.403 ms 64 bytes from 192.168.1.101: icmp_seq=3 ttl=64 time=0.401 ms ^C # ping 192.168.1.100 PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data. 64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=0.324 ms 64 bytes from 192.168.1.100: icmp_seq=2 ttl=64 time=0.323 ms 64 bytes from 192.168.1.100: icmp_seq=3 ttl=64 time=0.320 ms ^C
続いて各サービスを定義する。
まずApache。RAはapacheを使用する。
# crm configure primitive httpd ocf:heartbeat:apache params \ configfile="/etc/httpd/conf/httpd.conf" statusurl="http://192.168.1.101:443/" \ op start interval="0" timeout="90" on-fail="restart" \ op monitor interval="10" timeout="60" on-fail="restart" \ op stop interval="0" timeout="300" on-fail="block"
(*) statusurlはRAの仕様上「http://」で始まらなければならない。SSLサイトの場合は「http://xxx.xxx.xxx.xxx:443/」のように指定する。
次にSamba。RAは用意されていないのでSamba付属のinitスクリプト(LSB)を使用する。
# crm configure primitive nmb lsb:nmb \ op start interval="0" timeout="15" on-fail="restart" \ op monitor interval="15" timeout="15" on-fail="restart" \ op stop interval="0" timeout="15" on-fail="block" # crm configure primitive smb lsb:smb \ op start interval="0" timeout="15" on-fail="restart" \ op monitor interval="15" timeout="15" on-fail="restart" \ op stop interval="0" timeout="15" on-fail="block"
Pacemakerで規定する故障には以下の3種類がある。
start
起動失敗
stop
停止失敗
monitor
監視による検出
故障が発生した際はon-fail="xxx"の設定に応じた動作を行う。指定できる動作には以下のものがある。
block
故障したリソースの管理を停止し待機する。
fence
リソース故障が発生したメンバーノードをSTONITHによって再起動し、フェールオーバする。
ignore
何の処理も行わない。
stop
故障したリソースを停止し、他のメンバーノードへフェールオーバさせない。
restart
故障したリソースを他のメンバーノードへフェールオーバする(デフォルト)。
仮想IPとサービスの定義が終わったのでサービス毎のグルーピングを行う。グループ名には任意の名前が指定できる。
web
Apache用仮想IPとApacheのグルーピング
# crm configure group web vip_httpd httpd
samba
Samba用仮想IPとSambaのグルーピング
# crm configure group samba vip_samba nmb smb
これでグループ単位でフェールオーバやオンライン/オフラインの制御ができるようになる。
# crm_mon -A ============ Last updated: Mon Oct 7 20:46:35 2013 Stack: Heartbeat Current DC: s1 (b7cf0247-85a1-472a-8430-fb38728488fd) - partition with quorum Version: 1.0.13-30bb726 2 Nodes configured, unknown expected votes Online: [ s1 s2 ] Resource Group: web vip_httpd (ocf::heartbeat:IPaddr2): Started s1 httpd (ocf::heartbeat:apache): Started s1 Resource Group: samba vip_samba (ocf::heartbeat:IPaddr2): Started s1 nmb (lsb:nmb): Started s1 smb (lsb:smb): Started s1 Node Attributes: * Node s1: + s2-p4p1 : up * Node s2: + s1-p4p1 : up
グループやリソース、ノードの制御はcrmコマンドで行う。以下に一例を示す。
フェールオーバ
# crm resource move web s2 force
グループ停止
# crm resource stop web
リソースに故障履歴(Faied actions)が付いた場合のクリーンアップ
# crm resource cleanup httpd s1
フェールオーバ/フェールバック先に移動禁止フラグが付いた場合のクリア
# crm resource unmove httpd
ノードスタンバイ(当該ノード上でリソースが動作している場合フェールオーバする)
# crm node standby s1
(*)ノードをメンテナンスする場合などに使用
ノードオンライン
# crm node online s1
参考資料
今回のようにシンプルな構成であれば比較的簡単に構築ができるが、複雑な構成の場合は構築や障害発生時などに対応に時間がかかることが考えられるので、以下に参考資料を紹介しておく。
Pacemakerでかんたんクラスタリング体験してみよう! - 技術評論社
連載記事 「Heartbeatでかんたんクラスタリング」 - @IT
体験! 新しくなったLinux-HA (1/3) - @IT
Pacemaker + Heartbeat による Web サーバークラスタ構築 - NETWORK ENGINEER BLOG
2017/08/26更新
対応バージョン: Vagrant 1.4.3, Pacemaker 1.0.13, Heartbeat 3.0.5, Apache 2.2.15, Tomcat 7.0.56
Pacemakerでリソースグループが自ホストで稼動している時のみ処理を行いたい場合は以下のようなスクリプトを書けばよい。
myhost=`uname -n` runhost=`crm resource status <リソースグループ名> | awk '{print $NF}'` if [ ${myhost} = ${runhost} ]; then (任意の処理) fi
例)
2台のクラスタ構成において稼動系のホストでRedmineのリマインドメールを出すスクリプト
# crm_mon -f : Online: [ s1 s2 ] Resource Group: web vip_httpd (ocf::heartbeat:IPaddr2): Started s1 httpd (ocf::heartbeat:apache): Started s1 : # cat redmine.sh #!/bin/sh PATH=${PATH}:/usr/sbin # # check user # user=`whoami` if [ ${user} != "root" ]; then echo "execute root user" exit 100 fi # # check host & send mail # myhost=`uname -n` runhost=`crm resource status web | awk '{print $NF}'` if [ ${myhost} = ${runhost} ]; then cd /nas/contents/www/redmine-2.5.2 PATH=${PATH}:/usr/local/rbenv/shims rake redmine:send_reminders days=3 RAILS_ENV=production fi
2015/10/07更新
対応バージョン: Pacemaker 1.0.13, Heartbeat 3.0.5
以下のようなApacheのリソース定義がある(VIP定義とのグルーピング)。
# crm configure show : primitive httpd ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" statusurl="http://192.168.1.101/" \ op start interval="0" timeout="90" on-fail="restart" \ op monitor interval="10" timeout="60" on-fail="restart" \ op stop interval="0" timeout="300" on-fail="block" primitive vip_httpd ocf:heartbeat:IPaddr2 \ params ip="192.168.1.101" nic="eth1" cidr_netmask="24" \ op monitor interval="10" group web vip_httpd httpd \ meta target-role="Started" :
Apacheのサービスをserviceコマンドで普通に起動した場合はうまく動作するが、Pacemakerのリソースとして起動した場合は一瞬起動してすぐに停止してしまう。
正常
# service httpd start Starting httpd: [ OK ] # tail /var/log/httpd/error_log : [notice] Apache/2.2.15 (Unix) DAV/2 configured -- resuming normal operations
起動後すぐに停止
# crm resource start web # crm_mon -f : Online: [ s1 s2 ] Resource Group: web vip_httpd (ocf::heartbeat:IPaddr2): Started s1 httpd (ocf::heartbeat:apache): Stopped Migration summary: * Node s1: httpd: migration-threshold=1000000 fail-count=1000000 * Node s2: Failed actions: httpd_start_0 (node=s1, call=281, rc=1, status=complete): unknown error # tail /var/log/httpd/error_log : [notice] Apache/2.2.15 (Unix) DAV/2 configured -- resuming normal operations [error] [client 127.0.0.1] Directory index forbidden by Options directive: /var/www/html/ [notice] caught SIGWINCH, shutting down gracefully
これはPacemakerのApache Resource Agent(/usr/lib/ocf/resource.d/heartbeat/apache)がApacheの動作をモニタする際に以下の動きをするからである。
1.apache_monitor_basic()においてリソース定義のstatusurl=に指定したURLにアクセスし(358行目)、HTMLファイルが取得できないと次の処理に移り、363行目で呼び出したattempt_index_monitor_request()関数内において$OCF_RESKEY_statusurlに上記URLが設定されている(340行目)ために1を返し、結果的に371行目でエラー($OCF_ERR_GENERIC)を返す。
328 attempt_index_monitor_request() { : 340 if [ -n "$OCF_RESKEY_statusurl" ]; then 341 return 1; 342 fi : 357 apache_monitor_basic() { 358 if ${ourhttpclient}_func "$STATUSURL" | grep -Ei "$TESTREGEX" > /dev/null 359 then 360 return $OCF_SUCCESS 361 fi 362 363 attempt_index_monitor_request 364 if [ $? -eq 0 ]; then 365 return $OCF_SUCCESS 366 fi 367 368 if ! ocf_is_probe; then 369 ocf_log err "Failed to access httpd status page." 370 fi 371 return $OCF_ERR_GENERIC 372 }
2.エラーを受け取った上位の関数はapache_stop()を呼び出しApacheを停止する。
191 while : # wait until the user set timeout 192 do 193 apache_monitor 194 ec=$? 195 if [ $ec -eq $OCF_NOT_RUNNING ] 196 then 197 tries=`expr $tries + 1` 198 ocf_log info "waiting for apache $CONFIGFILE to come up" 199 sleep 1 200 else 201 break 202 fi 203 done 204 205 if [ $ec -ne 0 ] && silent_status; then 206 apache_stop 207 fi
これを回避するにはドキュメントルート(httpd.confのDocumentRootで指定したディレクトリ、/var/www/html等)にダミーのindex.htmlを置いておけばよい。
ダミーなので以下のような内容で構わない。
<html> </html>
この対処を行えばリソースは正常に起動する。
# crm resource cleanup httpd s1 # crm_mon -f : Online: [ s1 s2 ] Resource Group: web vip_httpd (ocf::heartbeat:IPaddr2): Started s1 httpd (ocf::heartbeat:apache): Started s1 :
関連資料・記事