文章 2:12 個防止系統降級 (Brownouts) 的 Kubernetes Probes
(12 Kubernetes Probes That Prevent Brownouts)
-
前言:Brownouts 的隱形威脅
- 段落重點:Brownouts(部分失效、回應變慢、空數據)比完全當機更可怕,因為它們會悄悄耗盡使用者信任。這篇文章提出了 12 種 Probe(探針)模式,教導 Kubernetes 什麼才是真正的「健康」。
- 總結:大部分事故不是完全中斷,而是部分故障。透過精確定義 Probe,可以讓 K8s 自動避開不健康的 Pod。
-
1. 基礎三劍客:Liveness, Readiness, Startup
- 段落重點:明確區分三種 Probe 的用途。
startupProbe給予啟動緩衝,readinessProbe控制流量進入,livenessProbe負責重啟死掉的進程。 - 範例保留:
/live:進程運行中(無依賴檢查)。/ready:安全服務用戶流量(依賴正常,背壓可接受)。/startup:啟動完成信號。
- 總結:信號設計必須分離,這是穩定性的基石。
- 段落重點:明確區分三種 Probe 的用途。
-
2. 感知依賴的 Readiness:世界沒準備好前別服務
- 段落重點:Readiness 應該檢查關鍵依賴(如 DB、Cache)。如果依賴斷線或佇列過深,應返回 503 拒絕流量,但保持
/live為綠燈以免被重啟。 - 範例保留:
if not db.ping(timeout=100): return 503 if queue.depth() > 50000: return 429 # Backpressure - 總結:避免將流量導向那些只會超時的 Pod。
- 段落重點:Readiness 應該檢查關鍵依賴(如 DB、Cache)。如果依賴斷線或佇列過深,應返回 503 拒絕流量,但保持
-
3. 延遲護欄 (Latency Guardrails)
- 段落重點:Brownouts 常表現為 p95/p99 延遲飄移。讓 Readiness 檢查滾動視窗內的延遲數據,如果過慢則暫時切斷流量。
- 總結:回應慢的 Pod 與失敗的 Pod 一樣有害。在尾部延遲恢復前,應將其隔離。
-
4. gRPC 健康檢查
- 段落重點:如果是 gRPC 優先的服務,應使用原生的
grpc.health.v1,而非僅依賴 HTTP。 - 總結:更精確的協議層級檢查,但建議仍保留一個微小的 HTTP
/health/live給不支援 gRPC 的 Sidecar 使用。
- 段落重點:如果是 gRPC 優先的服務,應使用原生的
-
5. 非 HTTP 進程的 Exec Probes
- 段落重點:對於 Queue Consumers 或 Cron Jobs,使用
exec執行命令來檢查健康狀況(如檢查佇列深度或進程狀態)。 - 總結:命令要保持微小且可預測,複雜腳本應內建於映像檔中。
- 段落重點:對於 Queue Consumers 或 Cron Jobs,使用
-
6. Startup Probe 與繁重的遷移
- 段落重點:若應用啟動時需跑遷移或暖存快取,必須使用
startupProbe保護,防止livenessProbe在啟動中途殺死 Pod。 - 總結:防止因啟動時間過長導致的 Crash Loop,特別是在 Schema 變更期間。
- 段落重點:若應用啟動時需跑遷移或暖存快取,必須使用
-
7. 簡單網路服務的 TCP Socket Probes
- 段落重點:對於 Proxy 或 Sidecar,如果「活著」等於「Socket 可接受連線」,使用 TCP Probe 即可。
- 總結:低開銷的檢查方式,適用於不需要應用層邏輯的服務。
-
8. 外部信號的 Readiness Gates
- 段落重點:使用
readinessGates讓 Pod 的就緒狀態取決於外部控制器(如 Feature Flags 或外部快取預熱狀態)。 - 總結:讓 K8s 等待外部條件滿足後才將 Pod 加入 Endpoints。
- 段落重點:使用
-
9. 將背壓 (Backpressure) 作為一等公民
- 段落重點:當積壓建立時(如 CPU 飽和或佇列滿),讓 Readiness 提早失敗,而不是讓延遲爆炸。
- 總結:主動拒絕流量(返回 429)比被動超時更好。
-
10. 磁碟與 File Descriptor 壓力
- 段落重點:檢查磁碟空間與 FD 使用量。應用常因無法寫入日誌或開啟 Socket 而「假性活著」。
- 範例保留:
if fs.percent_used("/var") > 90: return 503 if os.get_open_fds() > 0.9 * limit("nofile"): return 503 - 總結:這些是隱形的殺手,應納入健康檢查。
-
11. DNS 與時間健全性
- 段落重點:檢查 NTP 偏移與內部 DNS 解析。時間偏差或 DNS 失敗會導致神秘的超時。
- 總結:這些雖然不光鮮,但能節省數小時的除錯時間。
-
12. 藍綠與金絲雀發布的 Gating
- 段落重點:在金絲雀發布期間,透過 Header 或 Label 讓特定流量進入新 Pod,新 Pod 僅對帶有特定標記的請求回傳 200 Ready。
- 總結:在真實流量下驗證,而不會冒著全叢集 Brownout 的風險。
文章重點結論
架構師觀點:Kubernetes 的自我修復能力完全取決於我們如何定義「健康」。這篇文章強調了防禦性架構的重要性:健康檢查不應只是回傳
return 200的靜態 API。在生產環境中,必須實作依賴感知 (Dependency-aware)、背壓感知 (Backpressure-aware) 以及 延遲敏感 (Latency-sensitive) 的探針設計。透過精細配置startup、readiness和livenessprobe,我們可以將系統從「崩潰」轉變為「優雅降級」,這是構建高可用性微服務的關鍵實踐。