NETWORK ENGINEER BLOG

Tips and Reviews for Engineers

Pacemaker + Heartbeat による Web サーバークラスタ構築

Pacemaker とは

Heartbeat の後継ソフトウェアとして開発され、Heatbeat または Corosync のサブプロセスとして動作します。
Heartbeat と組み合わせて使用した場合、それぞれの役割は以下のとおりとなります。

Heatbeat
各ノードの死活監視を行います。
電源不良や kernel Panic 等、ハードウェアや OS に関する障害が発生した場合にこれを検知します。

Pacemaker
仮想 IP アドレス、Apache 等のサービスをリソースとして扱い、起動/停止、動作状態を監視します。
異常を検知すると、自動的に動作するリソースが起動するノードを制御(管理)します。

検証環境

想定環境
  • 各仮想マシンの CPU は1個、メモリは512MB とします。
  • 仮想ディスクは OS 用(8GB)と、データ用共有ディスク(10GB)の2つを用意します。
  • 共有ディスクは、RDM により仮想マシンから直接マウントし、SCSI バスの共有を行います。
  • 仮想ネットワークはサービス用(eth0)と、Heatbeat 用(eth1)の2つを用意します。
  • ソフトウェアは、CentOS5.6(64bit)を最小構成でインストールします。
検証構成

f:id:FriendsNow:20130305002541p:plain:w450

共有ストレージ設定

パーティションの作成(pm01)

fdisk -l で現状のディスク情報を確認します。

# fdisk -l

Disk /dev/sda: 8589 MB, 8589934592 bytes
255 heads, 63 sectors/track, 1044 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes

デバイス Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14        1044     8281507+  8e  Linux LVM

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes

ディスク /dev/sdb は正常な領域テーブルを含んでいません

fdisk で /dev/sdb にパーティションを作成します。

# fdisk /dev/sdb
デバイスは正常な DOS 領域テーブルも、Sun, SGI や OSF ディスクラベルも
含んでいません
新たに DOS ディスクラベルを作成します。あなたが書き込みを決定するまで、変更は
メモリ内だけに残します。その後はもちろん以前の内容は修復不可能になります。

このディスクのシリンダ数は 1305 に設定されています。
間違いではないのですが、1024 を超えているため、以下の場合
に問題を生じうる事を確認しましょう:
1) ブート時に実行するソフトウェア (例. バージョンが古い LILO)
2) 別の OS のブートやパーティション作成ソフト
   (例. DOS FDISK, OS/2 FDISK)
警告: 領域テーブル 4 の不正なフラグ 0x0000 は w(書き込み)によって
正常になります

コマンド (m でヘルプ): p

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes

デバイス Boot      Start         End      Blocks   Id  System

コマンド (m でヘルプ): n
コマンドアクション
   e   拡張
   p   基本領域 (1-4)
p
領域番号 (1-4): 1
最初 シリンダ (1-1305, default 1):
Using default value 1
終点 シリンダ または +サイズ または +サイズM または +サイズK (1-1305, default 1305): +100M

コマンド (m でヘルプ): n
コマンドアクション
   e   拡張
   p   基本領域 (1-4)
p
領域番号 (1-4): 2
最初 シリンダ (14-1305, default 14):
Using default value 14
終点 シリンダ または +サイズ または +サイズM または +サイズK (14-1305, default 1305):
Using default value 1305

コマンド (m でヘルプ): p

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes

デバイス Boot      Start         End      Blocks   Id  System
/dev/sdb1               1          13      104391   83  Linux
/dev/sdb2              14        1305    10377990   83  Linux

コマンド (m でヘルプ): w
領域テーブルは交換されました!

ioctl() を呼び出して領域テーブルを再読込みします。

警告: 領域テーブルの再読込みがエラー 16 で失敗しました: デバイスもしくはリソースがビジー状態です。
カーネルはまだ古いテーブルを使っています。
新しいテーブルは次回リブート時に使えるようになるでしょう。
ディスクを同期させます。

fdisk -l でパーティションが作成された事を確認します。

# fdisk -l

Disk /dev/sda: 8589 MB, 8589934592 bytes
255 heads, 63 sectors/track, 1044 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes

デバイス Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14        1044     8281507+  8e  Linux LVM

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes

デバイス Boot      Start         End      Blocks   Id  System
/dev/sdb1               1          13      104391   83  Linux
/dev/sdb2              14        1305    10377990   83  Linux
パーティション起動(pm02)

pm01 により作成の /dev/sdb 共有ストレージを pm02 の OS に認識させます。

# fdisk /dev/sdb

このディスクのシリンダ数は 1305 に設定されています。
間違いではないのですが、1024 を超えているため、以下の場合
に問題を生じうる事を確認しましょう:
1) ブート時に実行するソフトウェア (例. バージョンが古い LILO)
2) 別の OS のブートやパーティション作成ソフト
   (例. DOS FDISK, OS/2 FDISK)

コマンド (m でヘルプ): p

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes

デバイス Boot      Start         End      Blocks   Id  System
/dev/sdb1               1          13      104391   83  Linux
/dev/sdb2              14        1305    10377990   83  Linux

コマンド (m でヘルプ): w
領域テーブルは交換されました!

ioctl() を呼び出して領域テーブルを再読込みします。

警告: 領域テーブルの再読込みがエラー 16 で失敗しました: デバイスもしくはリソースがビジー状態です。
カーネルはまだ古いテーブルを使っています。
新しいテーブルは次回リブート時に使えるようになるでしょう。
ディスクを同期させます。
ファイルシステム作成(pm01 / pm02)

共有ストレージにファイルシステムを作成します。

# mke2fs -j /dev/sdb2
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
1297920 inodes, 2594497 blocks
129724 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2659188736
80 block groups
32768 blocks per group, 32768 fragments per group
16224 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 36 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

マウントポイント[/data]を作成します。

# mkdir /data

Pacemaker + Heartbeat 設定

Pacemaker インストール(pm01 / pm02)

Linux-HA Japan 提供のローカルリポジトリ + yum を使ってインストールします。
Linux-HA Japan 開発サイトからローカルリポジトリをダウンロードします。
本例では、pacemaker-1.0.11-1.2.1.el5.x86_64.repo.tar.gz をダウンロードしました。

ダウンロードしたローカルリポジトリを /tmp に展開します。

# mv pacemaker-1.0.11-1.2.1.el5.x86_64.repo.tar.gz /tmp/
# cd /tmp/
# tar zxvf pacemaker-1.0.11-1.2.1.el5.x86_64.repo.tar.gz

pacemaker heartbeat pm_extras をインストールします。

# cd pacemaker-1.0.11-1.2.1.el5.x86_64.repo
# yum -c pacemaker.repo install heartbeat.x86_64 pacemaker.x86_64 pm_extras

インストールを確認します。

# yum list pacemaker heartbeat pm_extras
Installed Packages
heartbeat.x86_64                    3.0.5-1.1.el5                      installed
pacemaker.x86_64                    1.0.11-1.2.el5                     installed
pm_extras.x86_64                    1.1-1.el5                          installed
Heartbeat 設定(pm01 / pm02)

ha.cf を設定します。

# vi /etc/ha.d/ha.cf
pacemaker on
logfacility local1
debug 0
udpport 694
keepalive 2
warntime 20
deadtime 24
initdead 48
ucast eth0 192.168.1.102  # peer-ip-addr
ucast eth1 172.16.1.102   # peer-ip-addr
node pm01
node pm02
watchdog /dev/watchdog
respawn root /usr/lib64/heartbeat/ifcheckd

authkeys を設定します。

# vi /etc/ha.d/authkeys
auth 1
1 crc

権限を設定します。

# chmod 600 /etc/ha.d/authkeys
Pacemaker 起動(pm01 / pm02)

pacemaker を起動します。

# service heartbeat start

起動を確認します。Online になるまで 1 分程度要します。

# crm_mon -A
============
Last updated: Tue Mar  5 02:35:09 2013
Stack: Heartbeat
Current DC: pm02 (420126ea-1e1e-4632-b4fb-eaa2a8915909) - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, unknown expected votes
0 Resources configured.
============

Online: [ pm02 pm01 ]

Node Attributes:
* Node pm02:
    + pm01-eth0                         : up
    + pm01-eth1                         : up
* Node pm01:
    + pm02-eth0                         : up
    + pm02-eth1                         : up
リソース制御設定(pm01)

crm コマンドを起動します。

# crm
crm(live)#

リソース設定モードに入ります。

crm(live)# configure
crm(live)configure#

現状の設定を確認します。

crm(live)configure# show
node $id="420126ea-1e1e-4632-b4fb-eaa2a8915909" pm02
node $id="ca3de0e0-dff2-4d13-a126-b9fbee7e3ec9" pm01
property $id="cib-bootstrap-options" \
        dc-version="1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87" \
        cluster-infrastructure="Heartbeat"

init スクリプトにより apache を制御します。

primitive apache lsb:httpd \
        op start interval="0s" timeout="60s" on-fail="restart" \
        op monitor interval="30s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="fence"

Filesystem リソースエージェントを使用し、Filesystem のリソース設定をします。

primitive mnt_fs ocf:heartbeat:Filesystem \
        params device="/dev/sdb2" directory="/data" fstype="ext3" \
        op monitor interval="20s" timeout="40s" \
        op start interval="0" timeout="60s" \
        op stop interval="0" timeout="60s"

pingd リソースエージェントを使用し、GW への Ping 死活監視リソース設定をします。

primitive pingd ocf:pacemaker:pingd \
        params name="default_ping_set" host_list="192.168.1.2" interval="10" timeout="10" attempts="5" multiplier="100" \
        op start interval="0" timeout="90" on-fail="restart" \
        op monitor interval="10" timeout="20" on-fail="restart" start-delay="1m" debug="true" \
        op stop interval="0" timeout="100" on-fail="block"

IPaddr2 リソースエージェントを使用し、仮想 IP のリソース設定をします。

primitive vip ocf:heartbeat:IPaddr2 \
        params ip="192.168.1.103" cidr_netmask="24" nic="eth0" iflabel="0" \
        op start interval="0s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="block"

STONITH 機能*1を無効にします。

property $id="cib-bootstrap-options" \
        dc-version="1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87" \
        cluster-infrastructure="Heartbeat" \
        stonith-enabled="false" \
        no-quorum-policy="ignore"

設定したリソースをグループ化します。

group Cluster vip mnt_fs apache

GW の Ping 死活監視は、全 Node で実行するようにクローン化します。

clone clone_ping pingd

Ping 死活監視で 100以下の値になった場合、VIP をフェイルオーバーします。

location vip_location vip \
        rule $id="vip_location-rule" -inf: not_defined default_ping_set or default_ping_set lt 100

自動フェイルバックを無効化します。*2

rsc_defaults $id="rsc-options" \
        resource-stickiness="INFINITY" \
        migration-threshold="3"

設定を反映します。

crm(live)configure# commit

設定を確認します。

crm(live)configure# show
primitive apache lsb:httpd \
        op start interval="0s" timeout="60s" on-fail="restart" \
        op monitor interval="30s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="fence"
primitive mnt_fs ocf:heartbeat:Filesystem \
        params device="/dev/sdb2" directory="/data" fstype="ext3" \
        op monitor interval="20s" timeout="40s" \
        op start interval="0" timeout="60s" \
        op stop interval="0" timeout="60s"
primitive pingd ocf:pacemaker:pingd \
        params name="default_ping_set" host_list="192.168.1.2" interval="10" timeout="10" attempts="5" multiplier="100" \
        op start interval="0" timeout="90" on-fail="restart" \
        op monitor interval="10" timeout="20" on-fail="restart" start-delay="1m" debug="true" \
        op stop interval="0" timeout="100" on-fail="block"
primitive vip ocf:heartbeat:IPaddr2 \
        params ip="192.168.1.103" cidr_netmask="24" nic="eth0" iflabel="0" \
        op start interval="0s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="block"
group cluster vip mnt_fs apache
clone clone_ping pingd
location vip_location vip \
        rule $id="vip_location-rule" -inf: not_defined default_ping_set or default_ping_set lt 100
property $id="cib-bootstrap-options" \
        dc-version="1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87" \
        cluster-infrastructure="Heartbeat" \
        stonith-enabled="false" \
        no-quorum-policy="ignore"
rsc_defaults $id="rsc-options" \
        resource-stickiness="INFINITY" \
        migration-threshold="3"

Pacemaker の状態を確認します。

# crm_mon -A
============
Last updated: Tue Mar  5 19:16:13 2013
Stack: Heartbeat
Current DC: pm02 (420126ea-1e1e-4632-b4fb-eaa2a8915909) - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, unknown expected votes
2 Resources configured.
============

Online: [ pm02 pm01 ]

 Resource Group: cluster
     vip        (ocf::heartbeat:IPaddr2):       Started pm01
     mnt_fs     (ocf::heartbeat:Filesystem):    Started pm01
     apache     (lsb:httpd):    Started pm01
 Clone Set: clone_ping
     Started: [ pm02 pm01 ]

Node Attributes:
* Node pm02:
    + default_ping_set                  : 100
    + pm01-eth0                         : up
    + pm01-eth1                         : up
* Node pm01:
    + default_ping_set                  : 100
    + pm02-eth0                         : up
    + pm02-eth1                         : up

設定を完全削除する場合は、Pacemaker を停止し、下記ファイルを削除します。

# rm -f /var/lib/heartbeat/crm/*
# rm -f /var/lib/heartbeat/crm/*
リソース移動確認(手動マイグレーション)

pm02 へのリソース移動をテストします。

[root@pm01 ~]# crm resource move cluster pm02 force

リソースが pm02 へ正常に移動する事を確認します。

[root@pm01 ~]# crm_mon -A
============
Last updated: Tue Mar  5 19:25:39 2013
Stack: Heartbeat
Current DC: pm02 (420126ea-1e1e-4632-b4fb-eaa2a8915909) - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, unknown expected votes
2 Resources configured.
============

Online: [ pm02 pm01 ]

 Resource Group: cluster
     vip        (ocf::heartbeat:IPaddr2):       Started pm02
     mnt_fs     (ocf::heartbeat:Filesystem):    Started pm02
     apache     (lsb:httpd):    Started pm02
 Clone Set: clone_ping
     Started: [ pm02 pm01 ]

Node Attributes:
* Node pm02:
    + default_ping_set                  : 100
    + pm01-eth0                         : up
    + pm01-eth1                         : up
* Node pm01:
    + default_ping_set                  : 100
    + pm02-eth0                         : up
    + pm02-eth1                         : up

リソースの unmove を行います。*3

[root@pm01 ~]# crm resource unmove cluster

Web サーバー監視設定

Web サーバー設定(pm01 / pm02)

yum により httpd パッケージをインストールします。

# yum install httpd

インストールを確認します。

# rpm -qa | grep httpd
httpd-2.2.3-76.el5.centos

httpd サービスを停止します。

# /etc/rc.d/init.d/httpd stop

httpd 自動起動をオフにします。

# chkconfig httpd off
ドキュメントルートの変更(pm01 / pm02)

ドキュメントルートを共有領域(/data)へ変更します。

# vi /etc/httpd/conf/httpd.conf
DocumentRoot "/data"

共有領域をマウントします。

# mount -t ext3 /dev/sdb2 /data/

共有領域へ index.html ファイルを作成します。

echo test > /data/index.html

共有領域をアンマウントします。

# umount -l /data/
Web サーバークラスタ動作確認

http://192.168.1.103 へアクセス可能な事を確認します。

プライマリ側の仮想 IP を持ち、共有領域をマウントしている事を確認します。

[root@pm01 ~]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:50:56:91:00:01 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.101/24 brd 192.168.1.255 scope global eth0
    inet 192.168.1.103/24 brd 192.168.1.255 scope global secondary eth0:0

[root@pm01 ~]# df -h
Filesystem          サイズ  使用  残り 使用% マウント位置
/dev/mapper/VolGroup00-LogVol00
                      6.7G  2.2G  4.2G  34% /
/dev/sda1              99M   13M   81M  14% /boot
tmpfs                 249M     0  249M   0% /dev/shm
/dev/sdb2             9.8G  151M  9.2G   2% /data

また、httpd サービスが起動している事を確認します。

[root@pm01 ~]# /etc/rc.d/init.d/httpd status
httpd (pid  11123) を実行中...

セカンダリ側では仮想 IP を持たず、共有領域をマウントしていない事を確認します。

[root@pm02 ~]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:50:56:91:00:02 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.102/24 brd 192.168.1.255 scope global eth0

[root@pm02 ~]# df -h
Filesystem          サイズ  使用  残り 使用% マウント位置
/dev/mapper/VolGroup00-LogVol00
                      6.7G  2.2G  4.2G  34% /
/dev/sda1              99M   13M   81M  14% /boot
tmpfs                 249M     0  249M   0% /dev/shm

また、httpd サービスが停止している事を確認します。

[root@pm02 ~]# /etc/rc.d/init.d/httpd status
httpd は停止しています
フェイルオーバー確認

プライマリ側(pm01)で、下記疑似障害を発生させた際、プライマリとセカンダリの状態が入れ替わります。

サービスネットワーク(eth0)を切断した場合

[root@pm01 ~]# crm_mon -A
============
Last updated: Tue Mar  5 19:37:38 2013
Stack: Heartbeat
Current DC: pm02 (420126ea-1e1e-4632-b4fb-eaa2a8915909) - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, unknown expected votes
2 Resources configured.
============

Online: [ pm02 pm01 ]

 Resource Group: Cluster
     vip        (ocf::heartbeat:IPaddr2):       Started pm02
     mnt_fs     (ocf::heartbeat:Filesystem):    Started pm02
     apache     (lsb:httpd):    Started pm02
 Clone Set: clone_ping
     Started: [ pm02 pm01 ]

Node Attributes:
* Node pm02:
    + default_ping_set                  : 100
    + pm01-eth0                         : dead
    + pm01-eth1                         : up
* Node pm01:
    + default_ping_set                  : 0             : Connectivity is lost
    + pm02-eth0                         : dead
    + pm02-eth1                         : up

サービス(apache)を kill した場合

[root@pm01 ~]# kill -9 11494
[root@pm01 ~]# crm_mon -A
============
Last updated: Tue Mar  5 19:44:41 2013
Stack: Heartbeat
Current DC: pm02 (420126ea-1e1e-4632-b4fb-eaa2a8915909) - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, unknown expected votes
2 Resources configured.
============

Online: [ pm02 pm01 ]

 Resource Group: cluster
     vip        (ocf::heartbeat:IPaddr2):       Started pm02
     mnt_fs     (ocf::heartbeat:Filesystem):    Started pm02
     apache     (lsb:httpd):    Started pm02
 Clone Set: clone_ping
     Started: [ pm02 pm01 ]

Node Attributes:
* Node pm02:
    + default_ping_set                  : 100
    + pm01-eth0                         : up
    + pm01-eth1                         : up
* Node pm01:
    + default_ping_set                  : 100
    + pm02-eth0                         : up
    + pm02-eth1                         : up

Failed actions:
    apache_monitor_30000 (node=pm01, call=43, rc=7, status=complete): not running
    apache_start_0 (node=pm01, call=45, rc=1, status=complete): unknown error

*1:制御不能のサーバを強制的に電源 OFF にします。

*2:heatbeat の auto_failback off は効きません。

*3:move コマンドは[リソース移動指示]+[移動元ノードでの当該リソース起動禁止フラグを付ける]という挙動になります。そのため、unmove により、このフラグを削除しないと、フェイルオーバーが動作しなくなります。