Kubernetes Probes - 健康檢查與自我修復
在 Kubernetes 中,Pod 狀態是 Running 只代表容器 process 有在跑,但不代表應用程式真的能服務。
如果你的 App 發生 Deadlock (死鎖),Process 還在但無法回應請求,K8s 預設是不會知道的。
為了讓 K8s 更聰明地管理應用程式,我們需要設定 Probes (探針)。
三種 Probe 類型
1. Liveness Probe (存活探針)
- 用途: 檢查 App 是否還活著。
- 行為: 如果檢查失敗,K8s 會 重啟 (Restart) 該 Pod。
- 適用: 當 App 發生無法復原的錯誤 (如 Deadlock) 時。
2. Readiness Probe (就緒探針)
- 用途: 檢查 App 是否準備好接收流量。
- 行為: 如果檢查失敗,K8s 會將該 Pod 從 Service 的 Endpoints 移除 (不導流量給它),但 不會重啟 它。
- 適用: 當 App 啟動需要一段時間載入資料,或者暫時過載無法服務時。
3. Startup Probe (啟動探針)
- 用途: 專門用於檢查啟動過程。
- 行為: 在它成功之前,Liveness 與 Readiness 不會執行。
- 適用: 啟動非常慢的 Legacy App。
設定範例
apiVersion: v1
kind: Pod
metadata:
name: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
# Liveness Probe: 檢查 /healthz,如果失敗就重啟
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3 # 啟動後延遲 3 秒才開始檢查
periodSeconds: 3 # 每 3 秒檢查一次
# Readiness Probe: 檢查 /readiness,如果失敗就暫時不導流
readinessProbe:
httpGet:
path: /readiness
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
# Startup Probe: 專門給啟動很慢的應用程式用的
# 在它成功之前,Liveness 和 Readiness 都不會執行
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30 # 最多失敗 30 次
periodSeconds: 10 # 每 10 秒檢查一次
# 總共給予 30 * 10 = 300 秒 (5分鐘) 的啟動時間
常用參數說明
除了上面範例用到的 initialDelaySeconds 和 periodSeconds,還有其他重要參數可以設定:
| 參數 | 預設值 | 說明 |
|---|---|---|
initialDelaySeconds | 0 | 容器啟動後,需等待多少秒才開始進行第一次探測。 |
periodSeconds | 10 | 執行的頻率,每隔多少秒執行一次探測。 |
timeoutSeconds | 1 | 每次探測的超時時間。如果 API 回應超過此時間,視為失敗。預設只有 1 秒,若 API 較慢請務必調整。 |
failureThreshold | 3 | 連續失敗幾次才算「真的失敗」。給予一些緩衝,避免因網路瞬斷誤判。 |
successThreshold | 1 | 探測失敗後,需連續成功幾次才算「恢復健康」。(Liveness 與 Startup 必須設為 1)。 |
探測方式 (Handlers)
除了 httpGet,還支援:
- tcpSocket: 嘗試建立 TCP 連線。如果能連上就算成功。
- exec: 在容器內執行指令。如果不吃
0(Exit Code 0) 就算成功。
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
最佳實踐
- 務必設定 Readiness Probe: 避免流量導向還沒初始化的 Pod,造成 50x 錯誤。
- Liveness Probe 要謹慎: 確保檢查的 API 真能反映 App 死活,不要因為資料庫連線超時就重啟 Web Server (這通常沒用且會造成雪崩)。
- initialDelaySeconds: 給 App 一點啟動時間,避免一啟動就被以為死掉而無限重啟。