全部產品
Search
文件中心

Alibaba Cloud Service Mesh:為網格內應用開啟健全狀態檢查重新導向

更新時間:Jun 30, 2024

由於Sidecar對網格內應用接收請求的攔截機制,如果您為加入Service MeshASM(即注入了Sidecar)中的應用配置了HTTP請求或TCP請求形式的健全狀態檢查,則健全狀態檢查可能出現不符合預期的行為,例如健全狀態檢查一直失敗。本文介紹如何為網格內應用開啟健全狀態檢查重新導向。

背景資訊

為網格內應用啟用HTTP和TCP請求的健全狀態檢查存在以下問題。因此,您需要基於Annotation方式為網格內應用開啟健全狀態檢查重新導向,讓健全狀態檢查恢複正常。

類型

說明

使用HTTP請求的健全狀態檢查

Kubernetes叢集由Kubelet服務統一發送Pod的健全狀態檢查請求,而在開啟了雙向TLS模式後,網格內應用被強制要求使用TLS方式進行通訊。由於Kubelet服務並非網格的一部分,該服務沒有Service Mesh為應用頒發的認證,導致使用HTTP方式的健全狀態檢查請求會被拒絕,健全狀態檢查一直失敗。

說明

如果您未在ASM中開啟雙向TLS模式,無需配置健全狀態檢查重新導向,就可以使用HTTP請求對應用Pod進行健全狀態檢查。

使用TCP請求的健全狀態檢查

由於Sidecar攔截請求的需要,網格內應用Pod的所有連接埠都會被監聽。在使用TCP請求方式的健全狀態檢查時,Kubelet服務會檢查應用Pod所配置的連接埠是否有應用進行中監聽,判斷應用的健康狀態。

由於上述原因,只要應用注入了Sidecar,且Sidecar正在運行,無論應用本身處於何種狀態,健全狀態檢查都始終會成功。例如,您為應用配置了錯誤連接埠,Pod的健全狀態檢查理應始終失敗,Pod應該處於未就緒狀態,但實際上健全狀態檢查成功。

預設情況下,網格拓撲圖中會顯示應用服務的健全狀態檢查的請求調用,但在很多情境下可能會混淆流量統計的結果。如果您需要移除這些內部的健全狀態檢查調用統計,可以為網格內應用開啟健全狀態檢查重新導向。

啟用HTTP請求的健全狀態檢查重新導向

本文以Nginx應用為例,在開啟雙向TLS模式後,為Nginx應用配置HTTP請求的健全狀態檢查,但是健全狀態檢查一直失敗,然後為Nginx應用開啟健全狀態檢查重新導向,查看Pod事件時無健全狀態檢查失敗事件,且Pod處於就緒狀態,說明為應用啟用HTTP請求的健全狀態檢查重新導向成功。

步驟一:開啟網格全域雙向TLS模式

  1. 登入ASM控制台

  2. 在左側導覽列,選擇服務網格 > 網格管理

  3. 網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理

  4. 在網格詳情頁面左側導覽列,選擇網格資訊安全中心 > 對等身份認證

  5. 對等身份認證頁面頂部,選擇命名空間,然後單擊設定全域雙向TLS模式

  6. 設定全域雙向TLS模式頁面,設定mTLS模式(命名空間級)STRICT - 嚴格遵循雙向TLS認證,單擊建立

步驟二:部署Nginx應用

  1. 擷取叢集KubeConfig並通過kubectl工具串連叢集

  2. 部署Nginx應用。

    1. 使用以下內容,建立http-liveness.yaml

      展開查看http-liveness.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-deployment
        labels:
          app: nginx
      spec:
        selector:
          matchLabels:
            app: nginx
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 80
              readinessProbe:
                httpGet:
                  path: /index.html
                  port: 80
                  httpHeaders:
                  - name: X-Custom-Header
                    value: hello
                initialDelaySeconds: 5
                periodSeconds: 3

      readinessProbe參數下設定httpGet,表示為該應用啟用HTTP請求的健全狀態檢查。

    2. 執行以下命令,部署Nginx應用。

      kubectl apply -f http-liveness.yaml
  3. 查看應用的健全狀態檢查狀態。

    1. 執行以下命令,查看Nginx應用的Pod名稱。

      kubectl get pod| grep nginx
    2. 執行以下命令,查看Pod事件。

      kubectl describe pod <Pod名稱>

      預期輸出:

      Warning  Unhealthy  45s               kubelet            Readiness probe failed: Get "http://172.23.64.22:80/index.html": read tcp 172.23.64.1:54130->172.23.64.22:80: read: connection reset by peer

      可以看到,針對Pod的HTTP健全狀態檢查失敗,使得Pod一直處於未就緒的狀態。

步驟三:為Nginx應用開啟健全狀態檢查重新導向

  1. 執行以下命令,編輯http-liveness.yaml

    vim http-liveness.yaml

    template參數下添加以下內容:

    annotations:
      sidecar.istio.io/rewriteAppHTTPProbers: "true"

    以下為添加Annotation註解後的http-liveness.yaml檔案:

    展開查看http-liveness.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 1
      template:
        metadata:
          labels:
            app: nginx
          annotations:
            sidecar.istio.io/rewriteAppHTTPProbers: "true"
        spec:
          containers:
          - name: nginx
            image: nginx
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 80
            readinessProbe:
              httpGet:
                path: /index.html
                port: 80
                httpHeaders:
                - name: X-Custom-Header
                  value: hello
              initialDelaySeconds: 5
              periodSeconds: 3
  2. 執行以下命令,部署Nginx應用。

    kubectl apply -f http-liveness.yaml

步驟四:驗證健全狀態檢查結果是否符合預期

  1. 查看Pod的健全狀態檢查狀態。

    1. 執行以下命令,查看Nginx應用的Pod名稱。

      kubectl get pod| grep nginx
    2. 執行以下命令,查看Pod事件。

      kubectl describe pod <Pod名稱>

      返回結果中不包含任務健全狀態檢查失敗的事件,Pod處於就緒狀態,啟用健全狀態檢查成功,符合預期。

  2. 執行以下命令,查看經過健全狀態檢查重新導向後的Pod YAML檔案。

    kubectl get pod nginx-deployment-676f85f66b-7vxct -o yaml

    展開查看預期輸出

    apiVersion: v1
    kind: Pod
    metadata:
      ...
      name: nginx-deployment-676f85f66b-cbzsx
      namespace: default
      ...
    spec:
      containers:
        - args:
            - proxy
            - sidecar
            - '--domain'
            - $(POD_NAMESPACE).svc.cluster.local
            - '--proxyLogLevel=warning'
            - '--proxyComponentLogLevel=misc:error'
            - '--log_output_level=default:info'
            - '--concurrency'
            - '2'
          env:
            ...
            - name: ISTIO_KUBE_APP_PROBERS
              value: >-
                {"/app-health/nginx/readyz":{"httpGet":{"path":"/index.html","port":80,"scheme":"HTTP","httpHeaders":[{"name":"X-Custom-Header","value":"hello"}]},"timeoutSeconds":1}}
          ...
        - image: nginx
          imagePullPolicy: IfNotPresent
          name: nginx
          ports:
            - containerPort: 80
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              httpHeaders:
                - name: X-Custom-Header
                  value: hello
              path: /app-health/nginx/readyz
              port: 15020
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 3
            successThreshold: 1
            timeoutSeconds: 1

    啟用了健全狀態檢查重新導向後,原先配置的健全狀態檢查連接埠由80改為15020,健全狀態檢查的路徑也由/index.html改為/app-health/nginx/readyz。同時,Pod中的Sidecar容器新增一個名為ISTIO_KUBE_APP_PROBERS的環境變數,其值為改寫健全狀態檢查之前的健全狀態檢查配置經過JSON序列化後的內容。

    對於網格內應用來說,15020是一個用於網格可觀測性的特殊連接埠,發送到該連接埠的流量不會被Sidecar攔截,因此不需要遵循TLS模式的要求。 在啟用健全狀態檢查重新導向後,運行於Sidecar容器中的pilot-agent服務會開啟監聽15020連接埠,接收來自Kubelet服務的健全狀態檢查,並根據ISTIO_KUBE_APP_PROBERS環境變數中配置的健全狀態檢查內容將健全狀態檢查請求轉寄至業務容器,從而使HTTP請求方式的健全狀態檢查正常運行。

啟用TCP請求的健全狀態檢查重新導向

本文以Nginx應用為例,為Nginx應用配置了錯誤連接埠,但是使用TCP的方式對應用的Pod健全狀態檢查仍然成功,不符合預期。然後為Nginx應用開啟健全狀態檢查重新導向,使用TCP的方式對應用的Pod健全狀態檢查失敗,符合預期,從而為應用成功啟用TCP請求的健全狀態檢查重新導向。

步驟一:部署Nginx應用

  1. 擷取叢集KubeConfig並通過kubectl工具串連叢集

  2. 部署Nginx應用。

    1. 使用以下內容,建立tcp-liveness.yaml

      以下內容中配置了一個錯誤的健全狀態檢查連接埠2940,由於Nginx應用不在2940連接埠開啟監聽,因此部署應用後健全狀態檢查應始終失敗,導致Pod一直處於未就緒狀態。

      展開查看tcp-liveness.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-deployment
        labels:
          app: nginx
      spec:
        selector:
          matchLabels:
            app: nginx
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 80
              readinessProbe:
                tcpSocket:
                  port: 2940
                initialDelaySeconds: 5
                periodSeconds: 3

      readinessProbe參數下設定tcpSocket,表示為該應用啟用TCP請求的健全狀態檢查。

    2. 執行以下命令,部署Nginx應用。

      kubectl apply -f tcp-liveness.yaml
  3. 查看應用的健全狀態檢查狀態。

    1. 執行以下命令,查看Nginx應用的Pod名稱。

      kubectl get pod| grep nginx
    2. 執行以下命令,查看Pod事件。

      kubectl describe pod <Pod名稱>

      返回結果中不包含任何健全狀態檢查失敗事件,Pod處於就緒狀態,不符合預期結果。

步驟二:為Nginx應用開啟健全狀態檢查重新導向

  1. 執行以下命令,編輯tcp-liveness.yaml檔案。

    vim tcp-liveness.yaml

    tcp-liveness.yaml檔案中template參數下添加以下內容:

    annotations:
      sidecar.istio.io/rewriteAppHTTPProbers: "true"

    以下為添加Annotation註解後的tcp-liveness.yaml檔案:

    展開查看tcp-liveness.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 1
      template:
        metadata:
          labels:
            app: nginx
          annotations:
            sidecar.istio.io/rewriteAppHTTPProbers: "true"
        spec:
          containers:
          - name: nginx
            image: nginx
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 80
            readinessProbe:
              tcpSocket:
                port: 2940
              initialDelaySeconds: 5
              periodSeconds: 3
  2. 執行以下命令,部署Nginx應用。

    kubectl apply -f tcp-liveness.yaml

步驟三:驗證健全狀態檢查結果是否符合預期

  1. 查看應用的健全狀態檢查狀態。

    1. 執行以下命令,查看Nginx應用的Pod名稱。

      kubectl get pod| grep nginx
    2. 執行以下命令,查看Pod事件。

      kubectl describe pod <Pod名稱>

      預期輸出:

      Warning  Unhealthy  45s               kubelet            Readiness probe failed: HTTP probe failed with statuscode: 500

      可以看到返回結果中提示健全狀態檢查失敗,符合預期。

  2. 執行以下命令,查看經過健全狀態檢查重新導向的應用Pod YAML內容。

    kubectl get pod nginx-deployment-746458cdc9-m9t9q -o yaml

    展開查看預期輸出

    apiVersion: v1
    kind: Pod
    metadata:
      ...
      name: nginx-deployment-746458cdc9-m9t9q
      namespace: default
      ...
    spec:
      containers:
        - args:
            - proxy
            - sidecar
            - '--domain'
            - $(POD_NAMESPACE).svc.cluster.local
            - '--proxyLogLevel=warning'
            - '--proxyComponentLogLevel=misc:error'
            - '--log_output_level=default:info'
            - '--concurrency'
            - '2'
          env:
            ...
            - name: ISTIO_KUBE_APP_PROBERS
              value: >-
                {"/app-health/nginx/readyz":{"tcpSocket":{"port":2940},"timeoutSeconds":1}}
          ...
        - image: nginx
          imagePullPolicy: IfNotPresent
          name: nginx
          ports:
            - containerPort: 80
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /app-health/nginx/readyz
              port: 15020
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 3
            successThreshold: 1
            timeoutSeconds: 1
          ...

    啟用了健全狀態檢查重新導向後,可以發現原先的TCP請求健全狀態檢查被改寫為HTTP請求健全狀態檢查,健全狀態檢查連接埠由80改為15020,並配置了HTTP健全狀態檢查的路徑為/app-health/nginx/readyz。同時,Pod中的Sidecar容器也會新增一個名為ISTIO_KUBE_APP_PROBERS的環境變數,其值為改寫健全狀態檢查之前的TCP健全狀態檢查配置經過JSON序列化後的內容。

    對於TCP請求的健全狀態檢查,Service Mesh的健全狀態檢查重新導向實際做了與HTTP請求的健全狀態檢查相同的處理,將其改寫為一個15020連接埠的HTTP健全狀態檢查。同時在Pod內部,運行於Sidecar容器中的pilot-agent服務會開啟監聽15020連接埠,接收來自Kubelet服務的健全狀態檢查,並根據ISTIO_KUBE_APP_PROBERS環境變數中配置的TCP健全狀態檢查內容,對業務容器配置的TCP健全狀態檢查連接埠進行實際的探測。如果實際的TCP健全狀態檢查失敗,pilot-agent服務會返回500狀態代碼,以標識健全狀態檢查失敗。