我が家のメインの仮想化環境は、2台の物理マシン上で稼動する VMware ESXi 4.0 と VMware Server 2.0 だ。単に両方使いたいと言う理由で同居するこの 2製品は、DRBD + Heartbeat で HA クラスタリング構成とした仮想マシン (以下 VM) をそれぞれの上に乗せ、「なるべく止めたくない」 サービスの運用に一役買っている。

先日この HA クラスターの 1つのスタンバイ側 VM を過去のバックアップ・データから丸ごとリストアした際に、Heartbeat でペアを構成するノード間で正常に通信できない状態になった。Heartbeat は CentOS のパッケージで、バージョンは 2.1.3 (heartbeat-2.1.3-3.el5.centos)。HA の VM 2台はそれぞれ次のようなエラーを延々と吐き続け、当然フェイル・オーバーも機能しない。

vm1 (アクティブ側):

heartbeat[3278]: 2010/xx/xx_12:00:00 ERROR: should_drop_message: attempted replay attack [vm2]? [gen = 1220721049, curgen = 1220721050]

vm2 (スタンバイ側):

heartbeat[3443]: 2010/xx/xx_12:00:00 ERROR: Message hist queue is filling up (500 messages in queue)

さらにこの状態では、スタンバイ側の Heartbeat を終了できず、結果的にマシンをシャットダウンも再起動もできなくなる。再起動するにはリセットか強制停止するしかないので、非常に具合が悪い。

これは Heartbeat のペアが、マシンに固有の uuid で互いを識別し合っていることに起因する。設定ファイル /etc/ha.d/ha.cf 中で

uuidfrom nodename

と設定していない場合、uuid は /var/lib/heartbeat/hb_uuid として保存される。我が家では当時この設定になっていて、詳しくは調査していないが何らかのハッシュ値を元に生成されているであろう uuid は、同じ VM でもコピーすると変わってしまう。同じホスト名を名乗りつつ uuid が異なるマシンが登場したことで、正常な側から 「お前、本当にあいつなのか?」 と疑われてしまっていたわけだ。

このトラブルを解消するには、具合の悪い方 (今回はスタンバイ側) で Heartbeat の自動起動を無効にしてから、ムリヤリでも何でもいいので、とにかく再起動させる。次に正常な方 (同アクティブ側) の hb_uuid ファイルを削除かリネームで過去の記憶を抹消し、具合が悪い側で Heartbeat を起動させると、通信できるようになる。新しい hb_uuid は、Heartbeat を起動した際に自動生成される。

今回は VM のコピー (バックアップ・データからリストア) だったが、物理マシンでもサーバーの入れ替え時等、「新サーバーで旧サーバーのホスト名を引き継ぎ」 → 「旧サーバーから Heartbeat 設定をコピー」 と言うような状況で発生しそうだ。前述の "uuidfrom nodename" を指定すれば、各ペアの識別は ha.cf 中の "node" として指定したホスト名から生成されるようになる、即ちホスト名が同じなら uuid も一致するので、後難を排するためにも、我が家で Heartbeat を利用する VM は全てこの設定に切り替えた。

ところで 「以前の状態に戻す」 と言う、VM の特性を活用して復活させたマシンの設定やパッケージ、その他諸々を (なるべく) 最新の状態に復旧させるのはそれなりに面倒な作業だが、システム管理自動化ツールの Puppet はこんな場面でも活躍する。ただマシンを起動するだけで全自動復旧、と言うことも設定 (と運用) 次第で可能なので、未導入の方はぜひどうぞ。

Comments are closed.