您當前的位置:首頁 > 書法

應用優雅上下線

作者:由 阿里云云棲號 發表于 書法時間:2019-09-06

1。 概述

kubernetes滾動升級的過程:

叢集Deployment 或者 Statefulset 發生變化,觸發部署滾動升級;

根據 Deolyement 等配置,K8S叢集首先啟動新的POD來替代老 POD;

Deployemnt 根據配置排程 POD,拉取映象,此時 POD 進入 Pending 狀態;

POD 繫結到Node上,啟動容器,在就緒檢查readinessProbe 探針通過後,新的POD進入Ready狀態;

K8S叢集建立Endpoint,將新的POD納入Service 的負載均衡;

K8S叢集移除與老POD相關的Endpoint,並且將老POD狀態設定為Terminating,此時將不會有新的請求到達老POD,同時呼叫PreStop Hook執行配置的指令碼;

K8S叢集會給老POD傳送SIGTERM訊號,並且等待 terminationGracePeriodSeconds 這麼長的時間。(預設為30秒,可以根據優雅下線服務需要消耗時間調整)

超過terminationGracePeriodSeconds等待時間後, K8S叢集會強制結束老POD,在這個時間段內要將老 POD 資源釋放掉,否則可能殘留無用資源被佔用。

從以上過程可以看到,如果在terminationGracePeriodSeconds 沒有及時釋放服務註冊等資源資訊,Service 負載均衡的健康檢查又沒有檢查到老 POD服務已經掛掉,導致請求分發到這些 POD 上,從而觸發一系列的請求錯誤,因而需要配置優雅下線指令碼,在terminationGracePeriodSeconds 時間段內執行完畢。

2。優雅啟動

kubernetes 叢集提供了探針,類似健康檢查,只有該請求透過,新的 POD 才能進入 Ready 狀態,kubernetes叢集才會將新的 POD 納入 Service 的負載均衡。

因而如果該應用(POD)僅僅提供 service 配置的服務,不需要配置探針,就可以優雅啟動,但是實際 POD 往往還有 HSF,LWP,Dubbo等註冊於配置服務其實現負載均衡的服務,所以需要確保這些服務都已經啟動,所以需要配置相應的探針。

同時,任何一個服務可能在執行中因為某種原因不穩定,導致服務中斷,這個時候還需要配置livenessProbe探針,確保服務出故障時及時止損。

我們的應用主要有HSF,LWP 和 Https 服務,對於三種服務都有的應用,要求應用提供健康檢查的介面,能即時檢查三種服務都正常與否,然後做以下配置:

livenessProbe:

failureThreshold: 3

initialDelaySeconds: 30

periodSeconds: 30

successThreshold: 1

tcpSocket:

port: 5084

timeoutSeconds: 1

readinessProbe:

failureThreshold: 3

initialDelaySeconds: 30

periodSeconds: 30

successThreshold: 1

tcpSocket:

port: 5084

timeoutSeconds: 1

restartPolicy: Always

readinessProbe配置表示只有5804埠請求正常返回,pod 才會進入 ready 狀態,確保各種服務 ok 。

livenessProbe 表示每10s 探一下5804埠,如果返回失敗,達到閾值後,pod 會重啟,對於服務出問題的 POD 及時止損。

注意:readinessProbe探針的 探測頻率和延時時間,不健康閾值等資料要合理,部分應用啟動時間本身較長,如果設定的時間過短,會導致 POD 反覆無效重啟。

3。 優雅下線:

我們的應用雲上主要有 HSF,LWP 和 Https 服務,在 pod prestop裡設定執行摘除服務註冊資訊指令碼,來完成優雅下線。

https 服務基於 kubernetes 服務 Service 來實現服務暴露,在老 POD 狀態設定為Terminating後,就不會有請求達到,因而已經優雅下線;

lwp 服務,透過註冊 vipserver 來提供負載均衡,需要在下線前先摘除該服務註冊,防止 老POD 下線後還有請求達到老 POD;

HSF 服務透過註冊 configserver 來提供負載均衡,需要在下線前先摘除該服務註冊,防止 老POD 下線後還有請求達到老 POD。

yaml:

lifecycle:

preStop:

exec:

command:

- sudo

- ‘-u’

- admin

- /home/admin/shutdown。sh

- {app_name}

preStop在 pod 終止之前,執行指令碼 appctl。sh {app_name} stop。

終止 HSF 與 LWP 指令碼:

#!/bin/bash

APP_NAME=$1

## HEALTH_URL=“http://localhost:7002/health”

offline() {

echo “INFO: ${APP_NAME} try to offline。。。”

offline_lwp

offline_hsf

echo “INFO: ${APP_NAME} offline success”

return $?

}

offline_lwp() {

echo “offline lwp”

times=3

for e in $(seq 3); do

curl -s ——connect-timeout 3 ——max-time 5 ${offline_lwp_url}${APP_NAME} -o /dev/null

sleep 1

done

}

offline_hsf() {

check_hsf=`(/usr/sbin/ss -ln4 sport = :12200; /usr/sbin/ss -ln6 sport = :12200) | grep -c “:12200”`

check_pandora=`(/usr/sbin/ss -ln4 sport = :12201; /usr/sbin/ss -ln6 sport = :12201) | grep -c “:12201”`

echo “try to offline hsf。。。”

if [ $check_hsf -ne 0 -a $check_pandora -ne 0 ]; then

echo “start to offline hsf。。。。”

ret_str=`curl ——max-time ${HSF_ONLINE_TIMEOUT} -s “http://localhost:12201/hsf/offline?k=hsf” 2>&1`

if echo “$ret_str” | grep “server is unregistered on cs(dr)” &>/dev/null; then

echo “hsf offline success。”

return 0

else

echo “hsf offline failed。”

exit 9 # hsf offline failed

fi

else

if [ $check_hsf -eq 0 ]; then

echo “WARN: port 12200 cannot be detected。”

fi

if [ $check_pandora -eq 0 ]; then

echo “WARN: port 12201 cannot be detected。”

fi

echo “WARN: hsf offline failed。”

# DO NOT exit here

fi

}

echo “[stop 1] before call offline hsf,lwp 。。。”

本文作者:joezxh

原文連結

更多技術乾貨敬請關注雲棲社群知乎機構號:阿里云云棲社群 - 知乎

標簽: POD  offline  HSF  服務  下線