由于Sidecar對網格內應用接收請求的攔截機制,如果您為加入服務網格ASM(即注入了Sidecar)中的應用配置了HTTP請求或TCP請求形式的健康檢查,則健康檢查可能出現不符合預期的行為,例如健康檢查一直失敗。本文介紹如何為網格內應用開啟健康檢查重定向。
背景信息
為網格內應用啟用HTTP和TCP請求的健康檢查存在以下問題。因此,您需要基于Annotation方式為網格內應用開啟健康檢查重定向,讓健康檢查恢復正常。
類型 | 說明 |
使用HTTP請求的健康檢查 | Kubernetes集群由Kubelet服務統一發送Pod的健康檢查請求,而在開啟了雙向TLS模式后,網格內應用被強制要求使用TLS方式進行通信。由于Kubelet服務并非網格的一部分,該服務沒有服務網格為應用頒發的證書,導致使用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模式
登錄ASM控制臺。
在左側導航欄,選擇 。
在網格管理頁面,找到待配置的實例,單擊實例的名稱或在操作列中單擊管理。
在網格詳情頁面左側導航欄,選擇 。
在對等身份認證頁面頂部,選擇命名空間,然后單擊設置全局雙向TLS模式。
在設置全局雙向TLS模式頁面,設置mTLS模式(命名空間級)為STRICT - 嚴格遵循雙向TLS認證,單擊創建。
步驟二:部署Nginx應用
部署Nginx應用。
使用以下內容,創建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請求的健康檢查。
執行以下命令,部署Nginx應用。
kubectl apply -f http-liveness.yaml
查看應用的健康檢查狀態。
執行以下命令,查看Nginx應用的Pod名稱。
kubectl get pod| grep nginx
執行以下命令,查看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應用開啟健康檢查重定向
執行以下命令,編輯http-liveness.yaml。
vim http-liveness.yaml
在
template
參數下添加以下內容:annotations: sidecar.istio.io/rewriteAppHTTPProbers: "true"
以下為添加Annotation注解后的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
執行以下命令,部署Nginx應用。
kubectl apply -f http-liveness.yaml
步驟四:驗證健康檢查結果是否符合預期
查看Pod的健康檢查狀態。
執行以下命令,查看Nginx應用的Pod名稱。
kubectl get pod| grep nginx
執行以下命令,查看Pod事件。
kubectl describe pod <Pod名稱>
返回結果中不包含任務健康檢查失敗的事件,Pod處于就緒狀態,啟用健康檢查成功,符合預期。
執行以下命令,查看經過健康檢查重定向后的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應用
部署Nginx應用。
使用以下內容,創建tcp-liveness.yaml。
以下內容中配置了一個錯誤的健康檢查端口2940,由于Nginx應用不在2940端口開啟監聽,因此部署應用后健康檢查應始終失敗,導致Pod一直處于未就緒狀態。
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請求的健康檢查。
執行以下命令,部署Nginx應用。
kubectl apply -f tcp-liveness.yaml
查看應用的健康檢查狀態。
執行以下命令,查看Nginx應用的Pod名稱。
kubectl get pod| grep nginx
執行以下命令,查看Pod事件。
kubectl describe pod <Pod名稱>
返回結果中不包含任何健康檢查失敗事件,Pod處于就緒狀態,不符合預期結果。
步驟二:為Nginx應用開啟健康檢查重定向
執行以下命令,編輯tcp-liveness.yaml文件。
vim tcp-liveness.yaml
在tcp-liveness.yaml文件中
template
參數下添加以下內容:annotations: sidecar.istio.io/rewriteAppHTTPProbers: "true"
以下為添加Annotation注解后的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
執行以下命令,部署Nginx應用。
kubectl apply -f tcp-liveness.yaml
步驟三:驗證健康檢查結果是否符合預期
查看應用的健康檢查狀態。
執行以下命令,查看Nginx應用的Pod名稱。
kubectl get pod| grep nginx
執行以下命令,查看Pod事件。
kubectl describe pod <Pod名稱>
預期輸出:
Warning Unhealthy 45s kubelet Readiness probe failed: HTTP probe failed with statuscode: 500
可以看到返回結果中提示健康檢查失敗,符合預期。
執行以下命令,查看經過健康檢查重定向的應用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請求的健康檢查,服務網格的健康檢查重定向實際做了與HTTP請求的健康檢查相同的處理,將其改寫為一個15020端口的HTTP健康檢查。同時在Pod內部,運行于Sidecar容器中的pilot-agent服務會開啟監聽15020端口,接收來自Kubelet服務的健康檢查,并根據
ISTIO_KUBE_APP_PROBERS
環境變量中配置的TCP健康檢查內容,對業務容器配置的TCP健康檢查端口進行實際的探測。如果實際的TCP健康檢查失敗,pilot-agent服務會返回500狀態碼,以標識健康檢查失敗。