ものすごく久しぶりにqmail

をインストール。

qmail + vpopmail + ClamAV + S25R な環境。
細かいことは随分と忘れていたがとりあえずインストール・設定・テストまで完了。

・・・のつもりだったが運用に入った段階でメールが送れない、という事象が発生。
ログを調べると、

Feb 20 04:18:38 mail1 X-Qmail-Scanner-2.08: [mail1.hoge.com 12983159185704971] clamdscan: corrupt or unknown clamd scanner error or memory/resource/perms problem - exit status 512/2

なるエラー。
Clamdはyumでパッケージインストール。
どうやら現在のバージョンではデフォルトではClamdがclamavユーザで動作、
一方、smtpdはqmaildユーザで動作しているのでこれでパーミッション拒否となっていた。
なので、Clamdをrootで動くようにする。

/etc/clamd.conf

#User clamav  ←この行をコメントアウト

これでclamdを再起動して無事メールが送受信できるようになった。


しかし改めてqmail系はもう本当に古いな、と実感。
ここまで枯れているのは素晴らしいと思うが、昨今の迷惑メール対策などしようと思っても
できないことが多い OR ソースから再コンパイルということが多く、運用で既に動いてる環境では
ナカナカ難しい。

Postfixにも不満点は多いが、もっと勉強しなきゃ。

Heartbeat v3 + Pacemaker 再び

前回は2台のサーバをアクティブ・スタンバイとしてクラスタリングしただけなので話は簡単(でもなかったけど)。

今回の構成では、2台のサーバで1台はWeb、1台はDBが動いていて、それぞれがフェイルオーバーするようにしてみる。
とは言っても、Pacemakerの設定ファイルが長くなるだけで、やることはあまり変わらなかった。

Heartbeat v3 に関して詳細に記述してるサイトが少ないので、
インストール手順も含めて詳細に記述してみる。

要件

node1:Apacheが稼働
node2:PostgreSQLが稼働

node1故障時には、node2でApache+PostgreSQL
node2故障時には、node1でPostgreSQL+Apache

となるように。

node1:eth0=192.168.0.101 / eth1=172.23.5.101
node2:eth0=192.168.0.102 / eth1 = 172.23.5.102
仮想IPとして、Web用に192.168.0.100(eth0側)、DB用に172.23.5.100(eth1側)を使用。

OSはCentOS5.5

DRBDインストール・設定

まずはnode1側の作業。
HDDの空き領域にパーティションを作成。

#> fdisk /dev/sda
コマンド (m でヘルプ): p
/dev/sda1   *           1       10199    81923436   83  Linux
/dev/sda2           10200       10326     1020127+  82  Linux swap / Solaris

DRBDで使用するパーティションを作成

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

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

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

コマンド (m でヘルプ): p
デバイス Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1       10199    81923436   83  Linux
/dev/sda2           10200       10326     1020127+  82  Linux swap / Solaris
/dev/sda3           10327       35530   202451130   83  Linux
/dev/sda4           35531       60734   202451130   83  Linux

それぞれ200GBづつのパーティションを作って、それぞれにWebとDBのデータを配置。
マウントポイントは、/var/www と /var/pgsql にする。

drbdのインストール

#>yum install drbd83 kmod-drbd83

インストールしたdrbdが対応しているカーネルバージョンを確認

#>rpm -qi kmod-drbd83
kernel 2.6.18-194.el5 for the i686 family of processors.

現在のカーネル

#>uname -r
2.6.18-194.32.1.el5PAE

カーネルバージョンが違うので、対応カーネルを再インストール

#>yum -y install yum-allowdowngrade
#>yum --allow-downgrade -y install kernel-2.6.18-194.el5

/etc/grub.confを確認

default=2
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-194.el5)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-194.el5 ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-194.el5.img
title CentOS (2.6.18-194.32.1.el5)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-194.32.1.el5 ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-194.32.1.el5.img
title CentOS (2.6.18-194.32.1.el5PAE)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-194.32.1.el5PAE ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-194.32.1.el5PAE.img
title CentOS (2.6.18-194.el5PAE)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-194.el5PAE ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-194.el5PAE.img

インストールしたカーネルがデフォルトでロードされるように、default=の値を変更
上から順番に0、1、2となってる。default=0にして、リブート。

確認

#>uname -r
2.6.18-194.el5

/etc/drbd.confを編集

global { usage-count yes; }
common { syncer { rate 10M; } }
#Web用のDRBDリソース設定
resource web {
  protocol C;
  startup {
        degr-wfc-timeout 120;
  }
 net {
        cram-hmac-alg sha1;
        shared-secret "hogehoge";
  }
  on node1{
        device /dev/drbd0;
        disk /dev/sda3;
        address 172.23.5.101:7789;
        meta-disk internal;
  }
  on node2{
        device /dev/drbd0;
        disk /dev/sda3;
        address 172.23.5.102:7789;
        meta-disk internal;
  }
}

#DB用のDRBDリソース設定
resource db {
  protocol C;
  startup {
        degr-wfc-timeout 120;
  }
 net {
        cram-hmac-alg sha1;
        shared-secret "hogehoge";
  }
  on node1{
        device /dev/drbd1;
        disk /dev/sda4;
        address 172.23.5.101:7790;
        meta-disk internal;
  }
  on node2{
        device /dev/drbd1;
        disk /dev/sda4;
        address 172.23.5.102:7790;
        meta-disk internal;
  }
}

DRBDメタデータ作成

#> drbdadm create-md web
#> drbdadm create-md db

初期同期をスキップ

#> drbdadm -- 6::::1 set-gi web
#> drbdadm dump-md web > /tmp/md
#> sed -i -r -e 's/0xF{16}/0x0000000000000000/g' /tmp/md
#> drbdmeta /dev/drbd0 v08 /dev/sda3 internal restore-md /tmp/md ; rm -f /tmp/md
#>
#> drbdadm -- 6::::1 set-gi db
#> drbdadm dump-md db > /tmp/md
#> sed -i -r -e 's/0xF{16}/0x0000000000000000/g' /tmp/md
#> drbdmeta /dev/drbd1 v08 /dev/sda4 internal restore-md /tmp/md ; rm -f /tmp/md

なんか聞かれたらとりあえずyes
ここまでをnode2側でも同様に行う

node1、node2の両方でDRBD起動

#>chkconfig --add drbd
#>service drbd start

ファイルシステム(ext3)作成
node1:

#> drbdadm primary web
#>/etc/rc.d/init.d/drbd status
drbd driver loaded OK; device status:
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by mockbuild@builder10.centos.org, 2010-06-04 08:04:16
m:res  cs         ro                 ds                 p  mounted  fstype
0:web   Connected  Primary/Secondary  UpToDate/UpToDate  C  ←webはnode1がprimary
1:db   Connected  Secondary/Secondary  UpToDate/UpToDate  C
#>mkfs -t ext3 /dev/drbd0

node2:

#> drbdadm primary db
#>/etc/rc.d/init.d/drbd status
drbd driver loaded OK; device status:
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by mockbuild@builder10.centos.org, 2010-06-04 08:04:16
m:res  cs         ro                 ds                 p  mounted  fstype
0:web   Connected  Secondary/Primary  UpToDate/UpToDate  C
1:db   Connected  Primary/Secondary  UpToDate/UpToDate  C
#>mkfs -t ext3 /dev/drbd1

動作確認
node1:

#> mount /dev/drbd0 /var/www
#> touch /var/www/hoge.txt
#> umount /var/www
#> drbdadm secondary web

node2:

#> drbdadm primary web
#> mount /dev/drbd0 /var/www
#> ls /var/www
drwxr-xr-x  3 root root 4096  2月14  2011 hoge.txt
#>umount /var/www

Heartbeat v3 + Pacemaker

epelがyumで自動で入らないので、事前にいれておく

#>wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
#>rpm -ivh epel-release-5-4.noarch.rpm

2011/2/14現在、yumでheartbeatをインストールするとv2になるので、v3のレポジトリを入れておく
Linux-HA Japanが提供)

#>wget http://iij.dl.sourceforge.jp/linux-ha/49890/pacemaker-1.0.10-1.4.1.el5.i386.repo.tar.gz
#>mv pacemaker-1.0.10-1.4.1.el5.i386.repo.tar.gz /tmp
#>tar -zxf /tmp/pacemaker-1.0.10-1.4.1.el5.i386.repo.tar.gz
#>cd /tmp/pacemaker-1.0.10-1.4.1.el5.i386.repo
#>yum -c pacemaker.repo install corosync-1.2.5-1.3.el5.i386 heartbeat-3.0.4-1.el5.i386 pacemaker-1.0.10-1.4.el5.i386

/etc/ha.d/ha.cf

pacemaker on
logfacility local1

debug 0
udpport 694

keepalive 2
warntime 20
deadtime 24
initdead 48

ucast eth1 172.23.5.102 ←クラスタリングの相手側のIPアドレス。ここではnode2のIP。

node node1
node node2

watchdog /dev/watchdog

認証ファイル
/etc/ha.d/authkeys

auth 1
1 sha1 password

パーミッションを600

#> chmod 600 /etc/ha.d/authkeys

ログが標準ではsyslogに吐かれるので、別にしておく
/etc.syslog.conf

*.info;mail.none;authpriv.none;cron.none;local1.none            /var/log/messages
local1.*                                                           /var/log/ha-log

ここまでをnode2でも行う。
heartbeatをnode1,node2で起動

#> service heartbeat start
#>crm_mon
============
Last updated: Thu Feb 10 01:17:34 2011
Stack: Heartbeat
Current DC: node1 (43a6ee456af4-188e-4ec8-0a99-4416c25e) - partition wit
h quorum
Version: 1.0.10-da7075976b5ff0bee71074385f8fd02f296ec8a3
2 Nodes configured, unknown expected votes
0 Resources configured.
============

Online: [ node1 node2 ]

pacemakerのリソース設定。
/etc/ha.d/setting.txt

#WebのDRBD設定
primitive drbd_web ocf:linbit:drbd \
        params drbd_resource="web" \
        op start interval="0s" timeout="240s" on-fail="restart" \
        op monitor interval="11s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" role="Master" \
        op stop interval="0s" timeout="100s" on-fail="block"

#DBのDRBD設定
primitive drbd_db ocf:linbit:drbd \
        params drbd_resource="db" \
        op start interval="0s" timeout="240s" on-fail="restart" \
        op monitor interval="11s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" role="Master" \
        op stop interval="0s" timeout="100s" on-fail="block"        

#Webの仮想IPアドレス設定。IP、nic、ネットマスクは環境に合わせて変更
primitive ip_web ocf:heartbeat:IPaddr \
        params ip="192.168.0.100" \
                nic="eth0" \
                cidr_netmask="24" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

#DBの仮想IPアドレス設定。IP、nic、ネットマスクは環境に合わせて変更
primitive ip_db ocf:heartbeat:IPaddr \
        params ip="172.23.5.100" \
                nic="eth1" \
                cidr_netmask="24" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

#nicの死活監視用。ルーター(192.168.0.1)にpingを飛ばす
primitive pingd_web ocf:pacemaker:pingd \
        params \
                name="default_ping_set" \
                host_list="192.168.0.1" \
                multiplier="100" \
                dampen="0" \
        meta \
                migration-threshold="10" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

#同様にeth1側のnic死活監視用。
primitive pingd_db ocf:pacemaker:pingd \
        params \
                name="default_ping_set" \
                host_list="172.23.5.1" \
                multiplier="100" \
                dampen="0" \
        meta \
                migration-threshold="10" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

#Web用のDRBDのマウント情報
primitive fs_web ocf:heartbeat:Filesystem \
        params device="/dev/drbd0" directory="/var/www" fstype="ext3" \
        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"

#DB用のDRBDのマウント情報
primitive fs_db ocf:heartbeat:Filesystem \
        params device="/dev/drbd1" directory="/var/pgsql" fstype="ext3" \
        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"

#PostgreSQLのリソース設定
primitive postgresql ocf:heartbeat:pgsql \
        params pgctl="/usr/local/pgsql/bin/pg_ctl" \
        start_opt="-p 5432 -h 127.0.0.1" \
        psql="/usr/local/pgsql/bin/psql" \
        pgdata="/var/pgsql/data" \
        pgdba="postgres" \
        pgport="5432" \
        pgdb="template1" \
        op start interval="0s" timeout="120s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="120s" on-fail="block"

#Apacheのリソース設定
primitive apache ocf:heartbeat:apache \
        params configfile="/usr/local/apache/conf/httpd.conf" \
        port="80" \
        op start interval="0s" timeout="40s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="block"

#Web用、DB用にそれぞれグループ化
group group_db fs_db ip_db postgresql
group group_web fs_web ip_web apache

#DRBDの設定
ms ms_drbd_db drbd_db \
        meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
        
ms ms_drbd_web drbd_web \
        meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
 
#Ping設定
clone clnPingd_web pingd_web \
        meta clone-max="2" clone-node-max="1"

clone clnPingd_db pingd_db \
        meta clone-max="2" clone-node-max="1"

#どちらがマスターでどちらがスレーブかを設定。ここはDB用なので、node2がマスターになるようにする
location group_db-location group_db \
        rule 200: #uname eq node2 \
        rule 100: #uname eq node1 \
        rule -INFINITY: defined default_ping_set and default_ping_set lt 100

#DB用のDRBDのマスター/スレーブ設定。
location master-location_db ms_drbd_db \
        rule 200: #uname eq node2 \
        rule 100: #uname eq node1 \
        rule role=master -INFINITY: defined default_ping_set and default_ping_set lt 100

#同じくWeb用のマスター/スレーブ設定。node1がマスター
location group_web-location group_web \
        rule 200: #uname eq node1 \
        rule 100: #uname eq node2 \
        rule -INFINITY: defined default_ping_set and default_ping_set lt 100

#Web用のDRBDのマスター/スレーブ設定
location master-location_web ms_drbd_web \
        rule 200: #uname eq node1 \
        rule 100: #uname eq node2 \
        rule role=master -INFINITY: defined default_ping_set and default_ping_set lt 100

#DB用にDRBDをマウントしてから、PostgreSQLを起動
colocation db_on_drbd inf: group_db ms_drbd_db:Master
colocation clnPingd_db-colocation 1000: group_db clnPingd_db
order order_db_after_drbd inf: ms_drbd_db:promote group_db:start

#Web用にDRBDをマウントしてから、Apacheを起動
colocation web_on_drbd inf: group_web ms_drbd_web:Master
colocation clnPingd_web-colocation 1000: group_web clnPingd_web
order order_web_after_drbd inf: ms_drbd_web:promote group_web:start

property $id="cib-bootstrap-options" \
        cluster-infrastructure="openais" \
        expected-quorum-votes="2" \
        no-quorum-policy="ignore" \
        stonith-enabled="false" \
        startup-fencing="false" \
        dc-deadtime="20s"

#フェイルバックしないように
rsc_defaults $id="rsc-options" \
        resource-stickiness="INFINITY" \
        migration-threshold="1"

以下はnode1側だけでOK。node2には自動でHeartbeatが設定を伝えてくれる

#>crm configure
crm(live)configure# load replace /etc/ha.d/setting.txt
crm(live)configure# commit

crm_monをしばらく眺めてると起動の様子が見れる。

Online: [ node1 node2 ]

 Resource Group: group_db
     fs_db	(ocf::heartbeat:Filesystem):    Started node2
     ip_db	(ocf::heartbeat:IPaddr):        Started node2
     postgresql (ocf::heartbeat:pgsql): Started node2
 Resource Group: group_web
     fs_web     (ocf::heartbeat:Filesystem):    Started node1
     ip_web     (ocf::heartbeat:IPaddr):        Started node1
     apache     (ocf::heartbeat:apache):        Started node1
 Master/Slave Set: ms_drbd_db
     Masters: [ node2 ]
     Slaves: [ node1 ]
 Master/Slave Set: ms_drbd_web
     Masters: [ node1 ]
     Slaves: [ node2 ]
 Clone Set: clnPingd_db
     Started: [ node1 node2 ]
 Clone Set: clnPingd_web
     Started: [ node2 ]

StartにFailedしたら、設定ファイルの間違いを確認。Apacheが起動しないときは別記事を参照。
/var/log/ha-logも手がかりになる。
Pacemakerの設定を消すには、heartbeatを停止。

#>rm /var/lib/heartbeat/crm/*

heartbeatを起動、crm configureで設定ファイルを再度ロードすればいい。

/usr/lib/ocf/resource.d/heartbeatを見ると、MySQLPostfixXenvmwareなどいろいろ。
必要なパラメーターは単なるスクリプトファイルなので眺めていればなんとなく分かる。
MailToを使って、フェイルオーバー時にメール送信、みたいなこともできる(はず)。今度やってみよう。

参考サイト:
CentOSで自宅サーバ構築 様
Linux-HA Japan 様

Movable Typeが嫌い

タイトル通り。

Movable Typeが嫌い。サーバ管理者の立場として、だが。

古いサーバのリプレースで、コンテンツやDBを新サーバへ総引越し。
その中に古いMovable Type(ver3.1)が動いてる。
rsyncでそのままコピーしたものの、(Perlモジュールの)あれが足りないこれが足りない、とウルサイ。
まぁそれだけならひとつづつインストールしていけばいい。


mt-check.cgiも動いてエラーも無し。
念のため管理ページにログインして記事を投稿。再構築すると・・・・

Invalid version format (non-numeric data) at /htdocs/blog/lib/MT/Template/Context.pm line 407.

なるエラーが。


いつも通りgoogle先生に聞いてみるもイマイチ分からん。
Perlモジュールにversionっていうモジュールがあり、それの仕様が変わって
戻り値が恐らく数値型じゃなくなったのだろう。
ってところまでは分かった。が、これの修正方法が分からん。
versionというPerlモジュールを古いバージョンにするか、Movable Type側でどうにかするしかない。


もちろん開発元のSix Apartに聞けばいいんだろうけど、保守契約がどうの、バージョンが古い(現在の最新はVer5らしい)から
アップデートしろ、だの言われるのが目に見えて、それよりも今日中になんとかしなくてはいけないので、
そんな(サポートに聞くような)無駄な時間はかけたくない。
過去に何度か問い合わせもしたが、SixApart社のサポートの対応っぷりはM$と同程度、といった印象しかない。


ということで、有償ソフトってことはもう忘れて、Movable Typeのソースを読み始める。
そこでタイトルにもどるが「Movable Typeが嫌い」
なんの案件だったかは忘れたけど、数年前にもMovableTypeでドはまりしたことがあって、
それ以来、ともかく嫌い。


ソースがPerlなのはいいとして、そのソースコードの分かりにくさ世界選手権があれば間違いなく
No.1だろうと思うくらい分かりずらい。
オープンソースの世界にドップリ浸かってると、そもそもこんなものが
未だに「有償」というのが不思議。WordPressでいいじゃん。


問題のエラーが出てる箇所が、

sub _hdlr_mt_version {
    require MT;
    my $version = MT->VERSION;

単純にMTのバージョン番号を返してるだけじゃないの?なんでそんなんで致命的なエラーになるの??と
?マークのオンパレード。ますます嫌悪感が増して行く。


しばらく我慢して読んでたけど、もう面倒くさくなって、そもそもバージョン番号を返してるだけなら
それを数値で返してやればいいじゃん、と。

sub _hdlr_mt_version {
    require MT;
    my $version = '3.17';

・・・問題解決(笑)


もしまたこのサーバのリプレースが必要になったら、
その時は間違いなくWordPressに移行してもらおう。
もうMTで悩まされるのは二度とイヤじゃ。

手動でSMTP Auth

いつも忘れるのでメモ。

%> perl -MMIME::Base64 -e 'print encode_base64("[user name]\0[user name]\0[password]");'
xxxxxxxxxxxxxxxxx
%>telnet 192.168.0.100 587
Connected to 192.168.0.100 (192.168.0.100).
Escape character is '^]'.
220 mail.hoge.com ESMTP
EHLO localhost
250-mail.hoge.com
250-AUTH LOGIN CRAM-MD5 PLAIN
250-AUTH=LOGIN CRAM-MD5 PLAIN
250-PIPELINING
250 8BITMIME
AUTH PLAIN xxxxxxxxxxxxxxxxx
235 ok, go ahead (#2.0.0)

これで認証成功

Apache on Pacemaker でハマる

CentOSにDRBD+Heartbeat(v3)+Pacemakerでクラスタ構成。PostgreSQLApacheをリソース監視として組み込む。

crmのコマンドはさっぱり分からないまま、
とりあえずLinuxHAにアップされてる動画を皿のように見て、
設定もそのまま丸写ししてみる。

primitive drbd_pg ocf:linbit:drbd \
        params drbd_resource="r0" \
        op start interval="0s" timeout="240s" on-fail="restart" \
        op monitor interval="11s" timeout="60s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" role="Master" \
        op stop interval="0s" timeout="100s" on-fail="block"

primitive ip_pg ocf:heartbeat:IPaddr \
        params ip="192.168.0.180" \
                nic="eth0" \
                cidr_netmask="27" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

primitive pingd ocf:pacemaker:pingd \
        params \
                name="default_ping_set" \
                host_list="192.168.0.1" \
                multiplier="100" \
                dampen="0" \
        meta \
                migration-threshold="10" \
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="100s" on-fail="block"

primitive fs_pg ocf:heartbeat:Filesystem \
        params device="/dev/drbd0" directory="/var2" fstype="ext3" \
        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"

primitive postgresql ocf:heartbeat:pgsql \
        params pgctl="/usr/local/pgsql/bin/pg_ctl" \
        start_opt="-p 5432 -h 127.0.0.1" \
        psql="/usr/local/pgsql/bin/psql" \
        pgdata="/var2/pgsql/data" \
        pgdba="postgres" \
        pgport="5432" \
        pgdb="template1" \
        op start interval="0s" timeout="120s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="120s" on-fail="block"

primitive apache ocf:heartbeat:apache \
        params configfile="/usr/local/apache/conf/httpd.conf" port="80" \
        op start interval="0s" timeout="40s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="60s" on-fail="block"

group group_pg fs_pg ip_pg postgresql apache

ms ms_drbd_pg drbd_pg \        
meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"

clone clnPingd pingd \
        meta clone-max="2" clone-node-max="1"

location group_pg-location group_pg \
        rule 200: #uname eq ns1 \
        rule 100: #uname eq ns2 \
        rule -INFINITY: defined default_ping_set and default_ping_set lt 100

location master-location ms_drbd_pg \
        rule 200: #uname eq ns1 \
        rule 100: #uname eq ns2 \
        rule role=master -INFINITY: defined default_ping_set and default_ping_set lt 100

colocation pg_on_drbd inf: group_pg ms_drbd_pg:Master
colocation clnPingd-colocation 1000: group_pg clnPingd
order order_pg_after_drbd inf: ms_drbd_pg:promote group_pg:start

property $id="cib-bootstrap-options" \
        cluster-infrastructure="openais" \
        expected-quorum-votes="2" \
        no-quorum-policy="ignore" \
        stonith-enabled="false" \
        startup-fencing="false" \
        dc-deadtime="20s"

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

これを設定ファイルとして、/etc/ha.d/setting.txt に保存。
crmコマンドでこのファイルをloadして設定。
heartbeat起動。

#> crm configure
crm(live)configure# load replace /etc/ha.d/setting.txt
crm(live)configure# commit
#> service heartbeat start

これでDRBDのマウント、仮想IPの設定、PostgreSQLの起動までは成功。
が、Apacheの起動だけがどうしてもできない。crm_mon で見ると、

Failed actions:
apache_start_0 (node=ns1, call=9, rc=1, status=complete): unknown error apache_start_0
 (node=ns2, call=5, rc=1, status=complete): unknown error 

なんてエラーが。

google先生にいろいろなキーワードで検索するも、どうやら日本国内ではまだまだHeartbeat v3 + Pacemaker の
事例はあまりないようで、参考になる情報が見つからない。

なので、英語ページも片っ端から開いて見るも、出てくるのはhttpd.confに

ExtendedStatus On

<Location /server-status>
SetHandler server-status

Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Location>

を書け、と。「俺はそれでうまくいった!」そんなことばかり。
「それでも動かんのじゃ!ボケ」と夜中の4時につぶやきながら、
仕方ないのでOCFのapacheスクリプトを眺めてみる。

/usr/lib/ocf/resource.d/heartbeat/apache

  1. httpd.confを読み込み
  2. apacheのpidファイルからプロセス番号を読んで
  3. そのプロセスが無ければ「落ちた」ということになって・・・・

ん?んん?apacheのpidファイル?

で、ふと気がついた。
そんなものどこにあるっけ?と。

PidFileディレクティブ

で、パッケージ版のApachehttpd.confを見てみると確かにこのPidFileディレクティブの記述がある。
自分はパッケージ嫌いでなんでも自分でコンパイルしてしまう派なので、当然Apacheも自分でソースからコンパイル
コンパイル版のApachehttpd.confには、このPidFileディレクティブがデフォルトでは無い罠。(*補足1)

ってことで、あとは話は簡単。httpd.confに1行追加。

PidFile /var/run/httpd.pid

で、heartbeatを再起動。。。。しばらく待つ。。。

apache     (ocf::heartbeat:apache):        Started ns1

キター。と、朝の5時に叫ぶ。

*補足1
コンパイル版のApacheではデフォルトでは、httpd.confからextra/httpd-mpm.conf がincludeされていないために
PidFileが指定されていないだけでした。これをincludeしてやればOKだと思われます。

*補足2
PHPフレームワークCakePHPを入れると、再びPacemakerのApche起動に失敗するようになった。
CakePHPの構造上、RewriteEngineを使うので、ドキュメントルートの/以下のURIRewriteされてしまうため発生。
Pacemakerから/server-status/server-statusとなるように、crmの設定を変更。

primitive apache ocf:heartbeat:apache \
        params configfile="/usr/local/apache/conf/httpd.conf" port="80" \
        statusurl="http://localhost/server-status/server-status" \ ←追加
        op start interval="0s" timeout="90s" on-fail="restart" \
        op monitor interval="10s" timeout="60s" on-fail="restart" \
        op stop interval="0s" timeout="300s" on-fail="block"

httpd.confを変更

ExtendedStatus On

<Location /server-status/server-status>
SetHandler server-status

Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Location>

/server-status/ に.htaccessを置く

RewriteEngine off


これで問題解決。