一個小需求,自動重啟k8s集群中日志不刷新的POD
k8s
需求
日常工作中,所有項目都不是完美的,筆者就經常遇到這種情況,pod狀態是running,但是程序卻沒有響應。發生這種情況的原因有很多種,有可能是因為k8s健康檢查的原因,比如使用ps檢查進程;或者是程序內部死循環,但是不退出;再或者網絡閃斷,程序無法重連等等。
無論什么原因,都會有解決辦法,但是優化需要時間,在未完全解決之前,問題不能不解決,于是想到了一個臨時方案,因為筆者公司項目日志是直接打印在stdout的,發生了程序無響應的情況,比較簡單的一個辦法是判斷日志輸出的時間。基于此,可以簡單寫一個小腳本,發現日志長時間不輸出的時候,重啟pod。
思路
使用kubectl logs命令查看最后一條日志輸出的時間戳,與服務器時間對比,差值大于閾值,則重啟相應POD。當然,這只是一個簡單的思路,并不適用于大部分場景,但是適合筆者公司,因為核心項目請求量很大,但凡是超過1分鐘日志不刷新,基本可以斷定100%出現問題了。
此思路其實也是拋磚引玉,希望能給大家一些靈感,如果有什么更好的辦法,也可以與筆者溝通交流。
簡單實現
shell比較簡單,直接與服務器交互也比較友好,就是用shell來寫吧。
- #!/bin/sh
- # 獲取當前UTC時間utc_now=`date -u`
- # 將時間轉換為timestamptimestamp_now=`date -d "$utc_now" +%s`
- function restart_pod() {
- for i in `kubectl get pod -n iot|grep PODNAME|awk '{print $1}'`;do
- for time in `kubectl logs --tail=1 --timestamps $i -n iot | awk '{print $1}'`;do
- timestamp_pod=`date -d "$time" +%s`
- delay=$(($timestamp_now-$timestamp_pod)) echo $i:$delay if [ "$delay" -ge "30" ];then
- echo "Pod $i 30S內沒有最新日志產生,重啟pod!"
- echo $i kubectl delete pod $i -n iot --force --grace-period=0
- curlwxFunc "Pod $i 30S內沒有最新日志產生,重啟pod!(生產環境)"
- fi done done}function curlwxFunc() {
- JSON='{
- "msgtype": "text",
- "text": {
- "content": "'$1'"
- }
- }'
- curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx' \
- -H 'Content-Type:application/json' \
- -d "${JSON}"
- }restart_pod
腳本很簡單,先查詢pod,然后看pod最后一條日志時間,與服務器時間對比,延遲超過30s就重啟pod,并且調用企業微信接口發一條通知。
后記
此方法也是治標不治本,治標還需要從源頭解決,不過需要時間,再沒有解決之前,先用這個小腳本抗一抗吧。也歡迎大家拍磚。