哈囉,大家好,歡迎來到 K8s 的第七天!
在過去幾天,我們已經學會了如何部署 Deployment,怎麼注入設定 (ConfigMap
/ Secret
),也知道如何透過 Service 建立一個穩定的入口。表面上看起來,我們的應用程式好像已經能在 K8s 上穩定運行了。
但有沒有想過,一個 Pod 處於 Running
狀態,真的就代表裡面的應用程式是健康的嗎?答案是否定的。今天,我們就要來探討 K8s 的健康檢查機制 —— Probes (探針),看看它如何幫助我們理解應用程式的內部狀態。
Running
狀態的假象K8s 的 kubelet 會持續監控 Pod 中容器的行程。只要行程還在跑,Pod 狀態就會被標記為 Running
。然而,這其實是一種「假象」。
舉幾個例子:應用程式可能因為程式碼 bug 卡在無限迴圈裡,表面上活著,但已經完全不回應請求;又或者後端連不上資料庫,結果每個 API 請求都回傳 500 錯誤;甚至像一些大型 Java 應用,啟動時需要幾分鐘才能真正提供服務,這段時間內其實還沒準備好。
這些狀況在 K8s 看來,依然都是 Running
。結果就是:一個已經「死掉」的 Pod 會繼續佔著資源,或者 Service 把流量送到一個還沒準備好的 Pod,最後讓使用者看到滿滿的錯誤頁。
這就是為什麼我們需要 探針 (Probes),讓 K8s 更深入地去判斷應用程式到底健康不健康。
所謂 Liveness Probe,重點在於回答:「這個應用程式還活著嗎?」
kubelet 會定期執行探針,如果發現連續多次失敗,就會認定這個容器已經救不回來了,接著直接把它殺掉,並根據 Pod 的 restartPolicy(通常是 Always)重新啟動一個新的容器。
換句話說,Liveness Probe 是 K8s 自我修復能力的核心。沒有它,你的應用程式有可能永遠卡死在那裡。
相比之下,Readiness Probe 要回答的問題不一樣,它更偏向於:「你現在準備好接受流量了嗎?」
當 Readiness Probe 失敗時,kubelet 並不會殺死容器,而是把這個 Pod 從 Service 的端點列表中移除。這樣一來,流量就不會再被轉送過來,Pod 可以安心完成啟動,或者花時間從暫時性的故障中恢復。等到探針恢復成功,Pod 就會再度被加回 Service,重新開始接收流量。
這種設計對於處理應用啟動延遲,或者服務過載的情境,非常重要。
來實際修改 ota-backend
的 deployment.yaml
,為它加上 Liveness 與 Readiness Probes。最常見的做法是提供一個專門的健康檢查 API,例如 /healthz
或 /readyz
。
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: ota-backend
image: your-docker-id/ota-backend:1.0
ports:
- containerPort: 8080
livenessProbe: # 存活探針這邊
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 3
readinessProbe: # 就緒探針這邊
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
除了 httpGet,K8s 還提供了 tcpSocket 和 exec 兩種方式。前者是嘗試建立 TCP 連線,只要能連上就算成功;後者則是在容器內執行一個指令,只要 exit code 是 0 就視為成功。
有些應用程式特別慢,可能需要幾分鐘才能完全啟動。這種情況下,如果只有 Liveness Probe,就很容易被誤判為失敗,結果在還沒準備好前就被 kubelet 一直殺掉。
為了避免這個問題,K8s 提供了Startup Probe。在 Startup Probe 成功之前,Liveness 和 Readiness 都會被暫停執行。這樣一來,慢速啟動的應用也能安全完成初始化。
今天我們看到,單純依靠 Running
狀態其實是不夠的,因為它只能代表「行程還在」,卻無法真正反映應用程式的健康狀態。Liveness Probe 幫助我們決定何時要重啟一個失效的容器,Readiness Probe 則負責判斷什麼時候可以開始接收流量,而 Startup Probe 則是專門照顧啟動時間過長的應用。
接下來的問題是:如何把這個在叢集內部運行的服務,安全又高效地暴露給外部使用者?明天我們就會來認識 Kubernetes 的流量入口 —— Ingress!