NHN Cloud Meetup 編集部
NHN Cloudの技術ナレッジやお得なイベント情報を発信していきます
2019.09.26
4,168
レイヤ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 コネクションまで確認する必要があります。