NHN Cloud Meetup 編集部
NHN Cloudの技術ナレッジやお得なイベント情報を発信していきます
2019.09.26
4,614
レイヤ4(L4)スイッチで負荷分散設定をしている環境では、サービス機をなんらかの理由で振り分け対象から外したいことがあるでしょう。ヘルスチェックの仕組みとサービス機を振り分けから外すための留意点をまとめました。



#!/bin/bash
L4_HEALTHCHECK_IPS=("10.0.0.252" "10.0.0.253")
PORT=80
for i in ${L4_HEALTHCHECK_IPS[@]}
do
sudo iptables -A INPUT -s $i -p tcp --dport $PORT -j DROP #DISABLE HEALTH CHECK, $L4_HEALTHCHECK_IPSから$PORTで入ってくる要請をDROPするファイアウォールのルール追加
# sudo iptables -D INPUT -s $i -p tcp --dport $PORT -j DROP #ENABLE HEALTH CHECK, 上記ファイアウォールのルールを削除
done
その前に、TCP コネクションステータスについて簡単に説明します。
主要な部分だけを説明します。

#!/bin/bash
SERVICE_PORT=443
L4_HEALTH_CHECK_IPS=("10.0.0.253" "10.0.0.254")
grep_cond_exclude_ips=$(IFS='|'; echo "${L4_HEALTH_CHECK_IPS[*]}") #(L7 health check方式で) L4 health check IPを除く
if [ $(sudo netstat --tcp -np | grep ":$SERVICE_PORT " | grep -vE "$grep_cond_exclude_ips" | grep -i established | wc -l) -gt 0 ];
then
echo "User connection still exist" >&2
exit 1 #exit with error
else
echo "NO connection"
exit 0
fi
#!/bin/bash
ESTB_CHECK_MAX=3
RETRY_MAX=5
SLEEP_TIME=3 #second
SERVICE_PORTS=("80" "443")
L4_ENABLE_URL="http://127.0.0.1/actuator/health/up"
L4_DISABLE_URL="http://127.0.0.1/actuator/health/down"
SERVICE_CHECK_URL="http://127.0.0.1/actuator/health"
L4_HEALTH_CHECK_IPS=("10.0.0.253" "10.0.0.254")
func_disable_l7()
{
curl -XPUT $L4_DISABLE_URL
}
func_enable_l7_repeat()
{
retry=0
while [ $retry -lt $RETRY_MAX ]
do
curl -XPUT $L4_ENABLE_URL # Enable health check
sleep $SLEEP_TIME
[[$(curl -LI $SERVICE_CHECK_URL -o /dev/null -w '%{http_code}' -s | grep 200 | wc -l) -eq 1]] && break
((retry++))
echo "Service is down, retrying..."
done
if [ $retry == $RETRY_MAX ];
then
echo "FAILED to enable L7 healthcheck" >&2
exit 1
else
echo "SUCCESS to start"
exit 0
fi
}
func_check_no_conn_repeat()
{
estb_check_count=0
retry_count=0
grep_cond_ports=$(printf ":%s |" ${SERVICE_PORTS[*]} | head -c -1)
grep_cond_exclude_ips=$(IFS='|'; echo "${L4_HEALTH_CHECK_IPS[*]}") #exclude; because L4 request continuously regardless of health status
while [ $estb_check_count -lt $ESTB_CHECK_MAX -a $retry_count -lt $RETRY_MAX ]
do
sleep $SLEEP_TIME
echo "Checking established connection..."
conn=$(netstat -nt | grep -E "$grep_cond_ports" | grep -vE "$grep_cond_exclude_ips" | grep ESTABLISHED)
if [ $(echo $conn | wc -l) -gt 0 ];
then
echo "connection exist"
echo -e "$conn"
estb_check_count=0
((retry_count++))
else
echo "NO connection"
((estb_check_count++))
fi
done
if [ $retry_count == $RETRY_MAX ];
then
echo "User connection still exist" >&2
exit 1 #exit with error
else
exit 0
fi
}
case "$1" in
down)
func_disable_l7
sleep 10
func_check_no_conn_repeat
;;
up)
func_enable_l7_repeat
;;
*)
echo $"Usage: $0 {down|up}"
esac
ループバック(ex. lo:0)インターフェースを落とさなくても、L4スイッチからサービスを除外することができます。
パケット損失を最小限にするには、ESTABLISHEDされたTCP コネクションまで確認する必要があります。