dubbo 協議的 K8s pod 存活探針配置

潘大慶發表於2021-12-06

背景

某專案採用微服務架構,dubbo 框架,K8s 方式部署。

其中 HTTP 協議由閘道器應用統一處理,大部分應用僅提供 dubbo 協議。

 

目標

應用某個例項(pod)狀態異常時,嘗試自動重啟恢復。

 

解決

K8s 提供了3種存活探針(livenessProbe),以實現 pod 狀態異常時重啟。

HTTPGetAction 首先排除了,因為上文我們說了,HTTP 訪問由閘道器統一處理,應用本身沒有 HTTP 協議。

然後是 TCPSocketAction,該探針僅能確認 dubbo 埠是否為監聽狀態,無法實現應用狀態的的撥測。

最後是 ExecAction,該探針執行命令返回0判斷 pod 存活,非0則根據pod定義的重啟策略進行後續操作。

 

dubbo 框架從2.0.5 版本開始,支援通過 telnet 命令互動,我們可以使用 status 命令獲取應用本身即應用依賴的底層服務(註冊中心、資料庫等)的撥測結果。

我們只需要編寫一個簡單的 shell 指令碼,抓取 dubbo 的 status 命令結果,如果是 OK 或 WARN 則返回0,否則返回1,就可以使用 ExecAction 了。

#!/bin/bash

outputfile=/tmp/dubbo_health_check
dubbo_port=$1

(echo 'status -l'; sleep 1) | nc -w 3 127.0.0.1 ${dubbo_port} -o ${outputfile} > /dev/null

result=`grep summary ${outputfile}| awk '{print $4}' `

if [[ "${result}" == "OK" ]] || [[ "${result}" == "WARN" ]]
then
    exit 0
else
    exit 1
fi

 

pod yaml檔案中關於存活探針的部分如下所示

#(略)
        livenessProbe:
          exec:
            command:
            - /bin/bash
            - /opt/dubbo_health_check.sh
            - '20800'
          initialDelaySeconds: 600
          timeoutSeconds: 5
          periodSeconds: 60
          failureThreshold: 3
#(略)

 

注意點

  1. 按 dubbo 官方文件的說法,telnet 中執行 status 返回的結果應該和 status -l 中 summary 的結果一致,實際測試並非如此,建議使用 status -l 
  2. 頻繁執行 status -l 可能會有效能上的隱患,參考 https://www.jianshu.com/p/f6376c148f2c

  

總結

dubbo 官方提供了與 pod 探針對齊的方法(參見下文),但是在我們這個應用中因為閘道器和其他一些原因限制了 HTTP 協議,因此使用了上文這種替代方案。

每個專案/團隊都會有一些自己的特殊需求,本文只是提供一種思路,如果有更好的解決方案,歡迎在評論區提出討論(●ˇ∀ˇ●)

  

參考

容器探針
https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/#container-probes

Dubbo 與 pod 探針對齊
https://dubbo.apache.org/zh/docs/references/lifecycle/brief/

Dubbo Telnet 命令
https://dubbo.apache.org/zh/docs/v3.0/references/telnet/#status

 

相關文章