Istio 服務的健康檢查

Kubernetes 的存活探針 (liveness probe) 和就緒探針 (readiness probe) 說明了配置存活和就緒探針的幾種方式

  1. 命令
  2. HTTP 請求
  3. TCP 探針
  4. gRPC 探針

命令方法不需要任何變更即可運作,但 HTTP 請求、TCP 探針和 gRPC 探針需要 Istio 對 Pod 設定進行修改。

針對 liveness-http 服務的健康檢查請求是由 Kubelet 發送的。當啟用相互 TLS 時,這會成為一個問題,因為 Kubelet 沒有 Istio 發出的憑證。因此,健康檢查請求將會失敗。

TCP 探針檢查需要特殊處理,因為 Istio 會將所有傳入的流量重新導向至 sidecar,因此所有 TCP 連接埠看起來都是開啟的。 Kubelet 只會檢查是否有任何處理程序在指定的連接埠上監聽,因此只要 sidecar 正在執行,探針就會始終成功。

Istio 通過重寫應用程式 PodSpec 的就緒/存活探針來解決這兩個問題,以便將探針請求發送到 sidecar 代理

活性探針重寫範例

為了展示如何在應用程式 PodSpec 層級重寫就緒/存活探針,我們將使用 liveness-http-same-port 範例

首先為範例建立並標記一個命名空間

$ kubectl create namespace istio-io-health-rewrite
$ kubectl label namespace istio-io-health-rewrite istio-injection=enabled

並部署範例應用程式

$ kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: liveness-http
  namespace: istio-io-health-rewrite
spec:
  selector:
    matchLabels:
      app: liveness-http
      version: v1
  template:
    metadata:
      labels:
        app: liveness-http
        version: v1
    spec:
      containers:
      - name: liveness-http
        image: docker.io/istio/health:example
        ports:
        - containerPort: 8001
        livenessProbe:
          httpGet:
            path: /foo
            port: 8001
          initialDelaySeconds: 5
          periodSeconds: 5
EOF

部署完成後,您可以檢查 Pod 的應用程式容器,以查看變更的路徑

$ kubectl get pod "$LIVENESS_POD" -n istio-io-health-rewrite -o json | jq '.spec.containers[0].livenessProbe.httpGet'
{
  "path": "/app-health/liveness-http/livez",
  "port": 15020,
  "scheme": "HTTP"
}

原始的 livenessProbe 路徑現在對應到 sidecar 容器環境變數 ISTIO_KUBE_APP_PROBERS 中的新路徑

$ kubectl get pod "$LIVENESS_POD" -n istio-io-health-rewrite -o=jsonpath="{.spec.containers[1].env[?(@.name=='ISTIO_KUBE_APP_PROBERS')]}"
{
  "name":"ISTIO_KUBE_APP_PROBERS",
  "value":"{\"/app-health/liveness-http/livez\":{\"httpGet\":{\"path\":\"/foo\",\"port\":8001,\"scheme\":\"HTTP\"},\"timeoutSeconds\":1}}"
}

對於 HTTP 和 gRPC 請求,sidecar 代理會將請求重新導向至應用程式並剝離回應主體,僅返回回應代碼。對於 TCP 探針,sidecar 代理接著會執行連接埠檢查,同時避免流量重新導向。

問題探針的重寫功能在所有內建的 Istio 組態設定檔中預設啟用,但可以如下所述停用。

使用命令方法的活性和就緒探針

Istio 提供一個 存活範例,其中實作了此方法。為了展示它在啟用相互 TLS 的情況下如何運作,首先為範例建立一個命名空間

$ kubectl create ns istio-io-health

若要設定嚴格的相互 TLS,請執行

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: "default"
  namespace: "istio-io-health"
spec:
  mtls:
    mode: STRICT
EOF

接下來,將目錄變更至 Istio 安裝的根目錄,並執行以下命令以部署範例服務

壓縮
$ kubectl -n istio-io-health apply -f <(istioctl kube-inject -f @samples/health-check/liveness-command.yaml@)

為了確認存活探針正在運作,請檢查範例 Pod 的狀態,以驗證它是否正在執行。

$ kubectl -n istio-io-health get pod
NAME                             READY     STATUS    RESTARTS   AGE
liveness-6857c8775f-zdv9r        2/2       Running   0           4m

使用 HTTP、TCP 和 gRPC 方法的活性和就緒探針

如先前所述,Istio 預設使用探針重寫來實作 HTTP、TCP 和 gRPC 探針。您可以針對特定的 Pod 或全域停用此功能。

停用 Pod 的探針重寫

您可以使用 sidecar.istio.io/rewriteAppHTTPProbers: "false" 註解 Pod 以停用探針重寫選項。 請務必將註解新增至 Pod 資源,因為它將會被忽略在其他任何地方(例如,在封閉的部署資源上)。

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: liveness-http
spec:
  selector:
    matchLabels:
      app: liveness-http
      version: v1
  template:
    metadata:
      labels:
        app: liveness-http
        version: v1
      annotations:
        sidecar.istio.io/rewriteAppHTTPProbers: "false"
    spec:
      containers:
      - name: liveness-http
        image: docker.io/istio/health:example
        ports:
        - containerPort: 8001
        livenessProbe:
          httpGet:
            path: /foo
            port: 8001
          initialDelaySeconds: 5
          periodSeconds: 5
EOF

此方法可讓您逐步停用個別部署的健康檢查探針重寫,而無需重新安裝 Istio。

全域停用探針重寫

使用 --set values.sidecarInjectorWebhook.rewriteAppHTTPProbe=false 安裝 Istio,以全域停用探針重寫。或者,更新 Istio sidecar 注入器的組態映射

$ kubectl get cm istio-sidecar-injector -n istio-system -o yaml | sed -e 's/"rewriteAppHTTPProbe": true/"rewriteAppHTTPProbe": false/' | kubectl apply -f -

清理

移除用於範例的命名空間

$ kubectl delete ns istio-io-health istio-io-health-rewrite
此資訊是否實用?
您是否有任何改進建議?

感謝您的回饋!