說說為啥寫本文
春節假前,生產環境(基於Kubernetes的PaaS平台OpenShift)出現使用健康檢測探針報錯,但應用Pod並未下線的情況,導致服務卡住(某一節點死鎖,Service總是負載均衡到此節點)。
查了OpenShift官方文檔對此並無提及,在 Kubernetes 官方倉庫的 Issue列表 中有所收獲,在這里簡單記錄下。(Kubernetes v1.15.12以上版本已解決)
簡單說來,這可能是 Kubernetes 歷史遺留的一個 Bug,不過值得肯定的是:問題根源在於Kubernetes對於健康檢測方式不同,對於運行時的報錯處理也不同,直接導致了健康檢測的報錯。
底層出錯不應該影響上層,上層本應防住的為啥不防住呢?你說是吧。
健康檢測基礎知識
健康檢測,顧名思義是對應用節點進行檢測,判斷該節點是否健康可提供服務。
在Kubernetes 提供了三種健康檢測的探針(Probes):
- Liveness Probe 存活探針,檢測Pod狀態是否正常,如不正常則刪除Pod,由Deployment自動創建新Pod
- Readiness Probe 就緒探針,檢測Pod容器內應用服務是否可用,如不可用,從Service列表中移出,不再有流量進入
- Startup Probe 啟動探針,Kubernetes 1.18開始出現的新探針,適用於應用啟動慢的服務使用,防止在服務正常啟動前被Liveness Probe判定為不健康狀態刪除Pod,與減少Readiness Probes頻繁失敗的問題
這三種探針都有相同的三種檢測方式,只不過它們對檢測結果的處理不同。三者均包含:
exec容器執行命令方式httpGetHTTP GET請求方式tcpSocket創建套接字方式
這里就不繼續展開了,參見文末官方文檔地址吧。
問題描述
生產環境中,使用了相對靈活的 exec 容器執行命令: curl http://localhost:8188/actuator/health/readiness,作為就緒探針(Readiness Probe),每10秒檢測一下服務狀態,在某個節點負載請求時,發生節點死鎖,命令執行超時無響應,超過超時時間探針報錯,但此節點未從Service列表中移出,導致集群其它節點沒有流量進入,服務處於不可用狀態。
報錯信息為 Readiness probe errored: rpc error: code = DeadlineExceeded desc = context deadline exceeded

為什么會發生此問題?
參考了這個issue中某位熱心網友提供的源碼注釋
即 exec 容器內執行命令的探針遇到錯誤時並未變更Pod的狀態,導致仍在負載均衡的列表中;其他探針中將檢測過程中遇到的所有錯誤,都算作檢測失敗,變更Pod狀態。
解決思路
問題本身出現在容器運行時上,但是問題反映在Kubernetes健康檢測時,所以最簡單的解決辦法是 使用其他檢測方式,如 httpGet 或 tcpSocket。
除此之外,升級Kubernetes 版本至 v1.15.12以上也可以解決問題,當然,要去根的話,需要升級 Containerd 版本了,一般對應 Docker 版本變化即可(Docker 綁定了 Containerd 管理容器)。
看來docker v19.03.6沒問題 😆

- Kubernetes v1.20以后移除Docker運行時這事和本文關系不大,因為錯誤出在底層Containerd上
- 我這邊公司用的OpenShift對應的Kubernetes版本太低,Docker也不能升(平台運維團隊是甲方……),所以只能改了httpGet方式檢測,另外因為OpenShift限制了界面上的端口號,又改了Deployment的yaml才搞定……
使用 httpGet 方式示例
重點關注 spec.containers 下的 livenessProbe 處定義,如更換其它探針類型,只換下名稱即可。
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
以上使用 httpGet方式,請求 http://localhost:8080/healthz,啟動時間延遲3秒,容器啟動3秒后,開始每隔3秒一次檢測。
總結
使用第三方服務還是需要深入了解下它的機制、有沒有什么坑等情況,以免出現碰到問題不知如何解決的被動局面。
路茫茫其修遠兮,吾將上下而求所。
參考
