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分鐘) 的啟動時間

常用參數說明

除了上面範例用到的 initialDelaySecondsperiodSeconds,還有其他重要參數可以設定:

參數預設值說明
initialDelaySeconds0容器啟動後,需等待多少秒才開始進行第一次探測。
periodSeconds10執行的頻率,每隔多少秒執行一次探測。
timeoutSeconds1每次探測的超時時間。如果 API 回應超過此時間,視為失敗。預設只有 1 秒,若 API 較慢請務必調整。
failureThreshold3連續失敗幾次才算「真的失敗」。給予一些緩衝,避免因網路瞬斷誤判。
successThreshold1探測失敗後,需連續成功幾次才算「恢復健康」。(Liveness 與 Startup 必須設為 1)。

探測方式 (Handlers)

除了 httpGet,還支援:

  1. tcpSocket: 嘗試建立 TCP 連線。如果能連上就算成功。
  2. exec: 在容器內執行指令。如果不吃 0 (Exit Code 0) 就算成功。
livenessProbe:
  exec:
    command:
      - cat
      - /tmp/healthy

最佳實踐

  • 務必設定 Readiness Probe: 避免流量導向還沒初始化的 Pod,造成 50x 錯誤。
  • Liveness Probe 要謹慎: 確保檢查的 API 真能反映 App 死活,不要因為資料庫連線超時就重啟 Web Server (這通常沒用且會造成雪崩)。
  • initialDelaySeconds: 給 App 一點啟動時間,避免一啟動就被以為死掉而無限重啟。