カスタム監視スクリプトの例

Ping Check

ハートビート経路をService Network(Floating IPを使用するネットワーク)と兼用している場合、クラスタマスタ(Recovery Master)のService NetworkのNICがLink Downすると、Floating IPの引き継ぎに失敗する場合があります。これは、クラスタマスタが適切にロックを開放しないために発生します。

このスクリプトは、Floating IPから指定のゲートウェイにPingを打って、それに失敗するとctdbサービスを強制停止することで、ロックを開放します。これにより、Floating IPの引き継ぎを実施することができます。

「GATEWAY」に適切なゲートウェイ(確実にpingに応答するIPアドレス)を指定してご利用ください。

/etc/ctdb/events.d/05.pingcheck

#!/bin/sh

#

# pingcheck event script for ctdb

# Force stop ctdb service when ping to $GATEWAY fails

# This will be used when heartbeat and floating ip's

# are on the same network.

#

. $CTDB_BASE/functions

loadconfig

GATEWAY=192.168.122.1

pingcheck()

{

ping $GATEWAY -c1 -q -w3 >/dev/null 2>&1

return $?

}

case "$1" in

monitor)

pingcheck

ret=$?

if [[ $ret -ne 0 ]]; then

service ctdb stop

exit 1

fi

exit 0

;;

*)

ctdb_standard_event_handler "$@"

;;

esac

exit 0

本スクリプトによる引き継ぎが発生した場合、障害ノードのctdbサービスが停止するので、障害回復後は、ctdbサービスを手動で起動することで、再度、クラスタに参加します。

また、本スクリプトによる強制停止より前にハートビート切断を検知すると、他のノードが一時的にクラスタから除外されるために、Floating IPの引き継ぎに時間がかかる恐れがあります。本スクリプトによる監視間隔(MonitorInterval)はハートビート切断検知間隔(KeepaliveInterval * KeepaliveLimit)より短く設定することをお勧めします。

GlusterFS Process監視

GlusterFS関連のプロセスが起動していることを "gluster vol status" の出力から確認します。必要なプロセスが起動していない際は、Floating IPの引き継ぎを発生します。

スクリプト冒頭の「host」変数には、"gluster vol status" のBrick状態の出力に含まれる自ノードのホスト名がセットされるようにしてください。「blacklist」変数には監視対象から除外するボリューム名を正規表現で記載します。「debug」に1をセットすると、CTDBのログにチェック結果が出力されます。

/etc/ctdb/events.d/25.glustercheck

#!/bin/sh

#

# glusterfs process monitoring

#

. $CTDB_BASE/functions

loadconfig

debug=0

host=$(hostname)

# This must be the hostname which appears in "gluster vol status" as below:

# Brick rhs20-01:/data/lockvol 24012 Y 23086

# ~~~~~~~~

blacklist="(vol01|vol02)"

# List of volumes to skip the check. Written in regex.

debug_log() {

if [[ debug -eq 1 ]]; then

echo $1

fi

}

volcheck() {

vols=$(gluster vol list)

if [[ $? -ne 0 ]]; then

echo "ERROR: failed to retrieve volume list."

return 1

fi

for vol in $vols; do

debug_log "-----"

if echo $vol | grep -E $blacklist; then

debug_log "Skipping: $vol"

continue

fi

debug_log "Checking status: $vol"

vol_status=$(gluster vol status $vol)

if [[ $? -ne 0 ]]; then

echo "ERROR: failed to retrieve volume status."

return 1

fi

if echo "$vol_status" | grep -qE "^Brick $host:"; then

is_online=$(echo "$vol_status" | grep -E "^Brick $host:" | awk -F'\t+' '{print $3}')

if [[ $is_online != "Y" ]]; then

echo "ERROR: brick on localhost is not online."

return 1

fi

debug_log "Brick on localhost is online."

fi

is_online=$(echo "$vol_status" | grep -E "NFS Server on localhost" | awk -F'\t+' '{print $3}')

if [[ $is_online != "Y" ]]; then

echo "ERROR: NFS Server on localhost is not online."

return 1

fi

debug_log "NFS Server on localhost is online."

is_online=$(echo "$vol_status" | grep -E "Self-heal Daemon on localhost" | awk -F'\t+' '{print $3}')

if [[ $is_online != "Y" ]]; then

echo "ERROR: self-heal Daemon on localhost is not online."

return 1

fi

debug_log "Self-heal Daemon on localhost is online."

debug_log "Succeeded: $vol"

done

debug_log "-----"

debug_log "Secceeded for all volumes."

return 0

}

case "$1" in

monitor)

debug_log "Do volcheck..."

volcheck

ret=$?

if [[ $ret -ne 0 ]]; then

echo "ERROR: failed volcheck."

exit 1

fi

debug_log "Succeeded volcheck."

debug_log "-----"

exit 0

;;

*)

ctdb_standard_event_handler "$@"

;;

esac

exit 0