カスタム監視スクリプトの例
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