天天看點

Kubernetes之健康檢查與服務依賴處理

本文講的是<b>Kubernetes之健康檢查與服務依賴處理</b>【編者的話】對線上業務來說,保證服務的正常穩定是重中之重,對故障服務的及時處理避免影響業務以及快速恢複一直是開發運維的難點。Kubernetes提供了健康檢查服務,對于檢測到故障服務會被及時自動下線,以及通過重新開機服務的方式使服務自動恢複。而對于服務依賴,無論資源描述檔案是pod, rc或deployment, 對應yaml檔案中描述僅是container啟動順序而非Container中服務啟動順序,Kubernetes提供了的Init Container,可處理服務之間依賴。

<a href="http://dockone.io/article/2526">【3 天燒腦式基于Docker的CI/CD實戰訓練營 | 北京站】本次教育訓練圍繞基于Docker的CI/CD實戰展開,具體内容包括:持續內建與持續傳遞(CI/CD)概覽;持續內建系統介紹;用戶端與服務端的 CI/CD 實踐;開發流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及實踐經驗分享等。</a>

簡單例子說明什麼是健康檢查以及服務依賴,比如一個應用分别有A、B、 C 3個服務,健康檢查就是如何确定A、B與C所在的Container處于運作狀态且服務工作正常;而對于服務依賴,假設服務A必須在服務B成功啟動之前啟動,而服務B必須在服務C成功啟動之前啟動,即啟動順序為A-&gt;B-&gt;C。

Kubernetes之健康檢查與服務依賴處理

Readness探針:主要用于判斷服務是否已經正常工作,如果服務沒有加載完成或工作異常,服務所在的Pod的IP位址會從服務的endpoints中被移除,也就是說,當服務沒有ready時,會将其從服務的load balancer中移除,不會再接受或響應任何請求。

無論對于Readness或Liveness探針,Handler均支援以下3種類型:ExecAction, TCPSocketAction, HTTPGetAction。每種類型說明與舉例如下:

探針檢查結果分為3種情況:

成功(Success):通過檢查。

失敗(Failure):檢查失敗。

未知(Unknown):檢查未知,需要人工幹預。

1. 如果服務的健康檢查(readiness)失敗,故障的服務執行個體從service endpoint中下線,外部請求将不會再轉發到該服務上,一定程度上保證正在提供的服務的正确性,如果服務自我恢複了(比如網絡問題),會自動重新加入service endpoint對外提供服務。

2. 另外,如果設定了Container(liveness)的探針,對故障服務的Container(liveness)的探針同樣會失敗,container會被kill掉,并根據原設定的container重新開機政策,系統傾向于在其原所在的機器上重新開機該container、或其他機器重新建立一個pod。

3. 由于上面的機制,整個服務實作了自身可用與自動恢複。

1. 建議對全部服務同時設定服務(readiness)和Container(liveness)的健康檢查

2. 通過TCP對端口檢查形式(TCPSocketAction),僅适用于端口已關閉或程序停止情況。因為即使服務異常,隻要端口是打開狀态,健康檢查仍然是通過的。

3. 基于第二點,一般建議用ExecAction自定義健康檢查邏輯,或采用HTTP Get請求進行檢查(HTTPGetAction)。

4. 無論采用哪種類型的探針,一般建議設定檢查服務(readiness)的時間短于檢查Container(liveness)的時間,也可以将檢查服務(readiness)的探針與Container(liveness)的探針設定為一緻。目的是故障服務先下線,如果過一段時間還無法自動恢複,那麼根據重新開機政策,重新開機該container、或其他機器重新建立一個pod恢複故障服務。

一個pod中可以有一或多個Init Container。Pod的中多個Init Container啟動順序為yaml檔案中的描述順序,且串行方式啟動,下一個Init/app Container必須等待上一個Init Container完成後方可啟動。例如,Init Container1-&gt; ... -&gt; Init Containern -&gt; app Container[1-n]。Init Container1成功啟動并且完成後,後續的Init Container和app Container才可以啟動,如Init Container啟動或執行相關檢查失敗,後續的init Container和應用Container将不會被執行啟動指令。

是以可利用Init Container來判斷app Container中被依賴的服務是否成功啟動。如被依賴的app Container服務啟動失敗,那麼利用Init Container啟動失敗可以阻止後續app Container服務的啟動。

前文已經提及,由于Init Container必須在app Containers啟動之前完成,是以可利用其特性,用作服務依賴處理。比如某一個服務A,需依賴db或memcached,那麼可以利用服務A pod的Init Container判斷db/memcached是否正常提供服務,如果啟動服務失敗或工作異常,設定Init Container啟動失敗,那麼pod中的服務A就不會被啟動了。

應用鏡像因安全原因等沒辦法安裝或運作的工具,可放到Init Container中運作。另外,Init Container獨立于業務服務,與業務無關的工具如sed, awk, python, dig等也可以按需放到Init Container之中。最後,Init Container也可以被授權通路應用Container無權通路的内容。

serviceA服務依賴serviceB,而serviceB采用上文提及Readness探針的HTTPGetAction Handler。

如果啟動serviceA Pod時,serviceB還沒有ready,通過kubectl get po -o wide檢視pod處于Init狀态

通過kubectl describe po serviceA-3071943788-g03wt檢視,可以看出app Container的啟動時在init Container啟動并成功完成後:

檢視docker Container log,init Container正在按照預先的設定,每3秒輪詢驗證serviceB健康檢查點serviceB:portB/pathB/

等待一段時間後,再次通過kubectl get po -o wide檢視pod處于Running狀态

如果pod重新開機了,所有init Container都需重新運作。Kubernetes禁止Init Container使用readiness探針,可以使用Pod定義 activeDeadlineSeconds 和 Container的 livenessProbe 防止 init containers 一直重複失敗. activeDeadlineSeconds 包含了 init container 啟動的時間。

歡迎轉載,請注明作者出處:張夏,FreeWheel Lead Engineer,DockOne社群

原文釋出時間為:2017-08-13

本文來自雲栖社群合作夥伴Dockerone.io,了解相關資訊可以關注Dockerone.io。

原文标題:Kubernetes之健康檢查與服務依賴處理