Kubernetes之健康檢查與服務依賴處理
【3 天燒腦式基於Docker的CI/CD實戰訓練營 | 北京站】本次培訓圍繞基於Docker的CI/CD實戰展開,具體內容包括:持續整合與持續交付(CI/CD)概覽;持續整合系統介紹;客戶端與服務端的 CI/CD 實踐;開發流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及實踐經驗分享等。
簡單例子說明什麼是健康檢查以及服務依賴,比如一個應用分別有A、B、 C 3個服務,健康檢查就是如何確定A、B與C所在的Container處於執行狀態且服務工作正常;而對於服務依賴,假設服務A必須在服務B成功啟動之前啟動,而服務B必須在服務C成功啟動之前啟動,即啟動順序為A->B->C。
健康檢查
使用Liveness及Readness探針
- Liveness探針:主要用於判斷Container是否處於執行狀態,比如當服務crash或者死鎖等情況發生時,kubelet會kill掉Container, 然後根據其設定的restart policy進行相應操作(可能會在本機重新啟動Container,或者因為設定Kubernetes QoS,本機沒有資源情況下會被分發的其他機器上重新啟動)。
- Readness探針:主要用於判斷服務是否已經正常工作,如果服務沒有載入完成或工作異常,服務所在的Pod的IP地址會從服務的endpoints中被移除,也就是說,當服務沒有ready時,會將其從服務的load balancer中移除,不會再接受或響應任何請求。
探針處理Handler型別
無論對於Readness或Liveness探針,Handler均支援以下3種型別:ExecAction, TCPSocketAction, HTTPGetAction。每種型別說明與舉例如下:
ExecAction:Container內部執行某個具體的命令,例子。
TCPSocketAction:通過container的IP、port執行tcp進行檢查, 例子。
HTTPGetAction: 通過container的IP、port、path,用HTTP Get請求進行檢查,例子。
探針檢查結果
探針檢查結果分為3種情況:
- 成功(Success):通過檢查。
- 失敗(Failure):檢查失敗。
- 未知(Unknown):檢查未知,需要人工干預。
健康檢查總結
探針型別 說明 通過健康檢查標準 ExecAction container內部執行shell命令 shell命令返回0 TCPSocketAction 通過container的IP、port執行tcp進行檢查 port是否開啟 HTTPGetAction 通過container的IP、port、path, 200<=返回值<400 用HTTP Get請求進行檢查
服務可用性與自動恢復
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恢復故障服務。
服務依賴
理解Init Container
一個pod中可以有一或多個Init Container。Pod的中多個Init Container啟動順序為yaml檔案中的描述順序,且序列方式啟動,下一個Init/app Container必須等待上一個Init Container完成後方可啟動。例如,Init Container1-> … -> Init Containern -> 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必須要在pod狀態變為Ready之前完成,所以其不需要readiness探針。另外在資源的requests與limits上與普通Container有細微差別,詳見 Resources,除以上2點外,Init Container與普通Container並無明顯區別。
Init Containers用途
- 前文已經提及,由於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無權訪問的內容。
Init Container處理服務依賴應用舉例
serviceA服務依賴serviceB,而serviceB採用上文提及Readness探針的HTTPGetAction Handler。
spec: initContainers: - name: init-serviceA image: registry.docker.dev.fwmrm.net/busybox:latest command: [`sh`, `-c`, "curl --connect-timeout 3 --max-time 5 --retry 10 --retry-delay 5 --retry-max-time 60 serviceB:portB/pathB/"] containers:
如果啟動serviceA Pod時,serviceB還沒有ready,通過kubectl get po -o wide檢視pod處於Init狀態
NAME READY STATUS RESTARTS AGE IP .l NODE serviceA-3071943788-8x27q 0/1 Init:0/1 0 20s 10.244.1.172 bjo-ep-svc-017.dev.fwmrm.net
通過kubectl describe po serviceA-3071943788-g03wt檢視,可以看出app Container的啟動時在init Container啟動併成功完成後:
Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 25s 25s 1 default-scheduler Normal ScheduledSuccessfully assigned serviceA-3071943788-g03wt to bjo-ep-dep-040.dev.fwmrm.net 25s 25s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net Normal SuccessfulMountVolume MountVolume.SetUp succeeded for volume "serviceA-config-volume" 25s 25s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net Normal SuccessfulMountVolume MountVolume.SetUp succeeded for volume "default-token-2c9j1" 24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Pulling pulling image "registry.docker.dev.fwmrm.net/ui-search-solr-data:latest" 24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "registry.docker.dev.fwmrm.net/busybox:latest" 24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Created Created container 24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Started Started container 20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Pulling pulling image "registry.docker.dev.fwmrm.net/infra/is:latest" 20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Pulled Successfully pulled image "registry.docker.dev.fwmrm.net/infra/is:latest" 20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Created Created container 19s 19s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Started Started container
檢視docker Container log,init Container正在按照預先的設定,每3秒輪詢驗證serviceB健康檢查點serviceB:portB/pathB/
docker logs 4fd58bf54f76 waiting for serviceB service waiting for serviceB service ... ...
等待一段時間後,再次通過kubectl get po -o wide檢視pod處於Running狀態
NAME READY STATUS RESTARTS AGE IP .l NODE serviceA-3071943788-g03wt 1/1 Running 0 1m 10.244.2.68 bjo-ep-dep-040.dev.fwmrm.net
如果pod重啟了,所有init Container都需重新執行。Kubernetes禁止Init Container使用readiness探針,可以使用Pod定義 activeDeadlineSeconds 和 Container的 livenessProbe 防止 init containers 一直重複失敗. activeDeadlineSeconds 包含了 init container 啟動的時間。
參考資料
Container Lifecycle Hooks: https://kubernetes.io/docs/con … ooks/
Attach Handlers to Container Lifecycle Events: https://kubernetes.io/docs/tas … vent/
Init Containers: https://kubernetes.io/docs/con … ners/
Init Container and Probe: https://blog.giantswarm.io/wai … etes/
Configure Pod Initialisation: https://kubernetes.io/docs/tas … ainer
Debug Init Containers: https://kubernetes.io/docs/tas … ners/
Delaying the deployment of our stubborn service: https://blog.giantswarm.io/wai … etes/
歡迎轉載,請註明作者出處:張夏,FreeWheel Lead Engineer,DockOne社群
原文釋出時間為:2017-08-13
本文作者:張夏
本文來自雲棲社群合作伙伴Dockerone.io,瞭解相關資訊可以關注Dockerone.io。
原文標題:Kubernetes之健康檢查與服務依賴處理
相關文章
- 叢集故障處理之處理思路以及健康狀態檢查(三十二)
- Kubernetes應用健康檢查
- Maven依賴衝突處理Maven
- win10依賴服務或組無法啟動怎麼辦 win10提示依賴服務或組無法啟動如何處理Win10
- Kubernetes-POD的健康檢查
- Nacos服務心跳和健康檢查原始碼介紹原始碼
- PHP中的服務容器與依賴注入的思想PHP依賴注入
- javacv-platform最小依賴處理JavaPlatform
- Win10提示“依賴服務或組無法啟動”怎麼辦 win10系統提示“依賴服務或組無法啟動”如何處理Win10
- 服務容器(自己總結)依賴注入依賴注入
- crontab 問題檢查與處理
- saltstack對遞迴依賴條件(死迴圈依賴)的處理遞迴
- spring原始碼深度解析— IOC 之 迴圈依賴處理Spring原始碼
- Kubernetes叢集健康檢查最佳實踐
- Kubernetes服務pod的健康檢測liveness和readiness詳解
- 如何在Java服務中實現自動化的健康檢查與自愈機制Java
- kubernetes實踐之三十七:Pod健康檢查
- 構建api gateway之 健康檢查APIGateway
- Nginx負載均衡之健康檢查Nginx負載
- 依賴倒置(DIP)與依賴注入(DI)依賴注入
- .Net Core中依賴注入服務使用總結依賴注入
- redis健康檢查與故障轉移Redis
- pytest 用例資料依賴如何處理
- 介面自動化測試-apiAutoTest 優化之資料依賴處理API優化
- Oracle 查詢鎖之間的依賴關係Oracle
- Spring 是怎麼處理迴圈依賴的?Spring
- 介面自動化如何處理介面依賴問題
- 死磕Spring之IoC篇 - 單例 Bean 的迴圈依賴處理Spring單例Bean
- 【CHECKPOINT】Oracle檢查點優化與故障處理Oracle優化
- Java後端分散式系統的服務健康檢查:Spring Boot HealthJava後端分散式Spring Boot
- idea檢視依賴樹Idea
- EntityFramework Core健康檢查Framework
- Health Monitor 健康檢查
- 自動部署模組所需環境依賴--bat批處理BAT
- 學習筆記——Maven 如何處理傳遞性依賴筆記Maven
- 使用IDEA模組之間依賴找不到依賴類Idea
- 微服務 - 叢集化 · 服務註冊 · 健康檢測 · 服務發現 · 負載均衡微服務負載
- socket服務叢集處理