如何收集pod重啓前現場

之前分享過幾篇優化pod重啓的文章,有朋友發私信問:看你的優化文章很過癮,可否分享下如何收集pod重啓前的現場。

 

案例分享-full gc導致k8s pod重啓

記一次k8s pod頻繁重啓的優化之旅

 

的確是個好問題,之前寫文章的時候忽略了這一點,一個完整的現場對破案的作用不言而喻,今天花點時間和大夥探討一下。

守株待兔階段

這個時期處於人工盯屏階段,打開rancher(一款k8s集羣管理工具)界面觀察pod的狀態,如果發現pod的狀態變成下圖(Container with unready status意味着健康檢查失敗)這樣的時候立刻進入容器的命令行使用jmap命令收集dump信息。

 顯然運氣的成分多一些,比較浪費時間。

 

全自動階段

盯屏效率太低,有沒有機制能在pod重啓前自動收集現場,無人值守,爲開發在事後分析提供充分的證據。

 

接下來就是今天的主角登場,容器的生命週期回調,Kubernetes 爲容器提供了生命週期回調。回調使容器能夠了解其管理生命週期中的事件,並在執行相應的生命週期回調時運行在處理程序中實現的代碼。

有兩個回調暴露給容器:

PostStart

這個回調在容器被創建之後立即被執行。但是,不能保證回調會在容器入口點(ENTRYPOINT)之前執行。沒有參數傳遞給處理程序。

PreStop

在容器因 API 請求或者管理事件(諸如存活態探針、啓動探針失敗、資源搶佔、資源競爭等) 而被終止之前,此回調會被調用。如果容器已經處於已終止或者已完成狀態,則對 preStop 回調的調用將失敗。在用來停止容器的 TERM 信號被髮出之前,回調必須執行結束。Pod 的終止寬限週期在 PreStop 回調被執行之前即開始計數, 所以無論回調函數的執行結果如何,容器最終都會在 Pod 的終止寬限期內被終止。沒有參數會被傳遞給處理程序。

我們最終決定藉助PreStop回調來實現自動收集現場,配置如下:

lifecycle:
          preStop:
            exec:
              command:
              - /bin/sh
              - -c
              - pid=`ps -ef |grep java | grep -v grep |awk '{print $1}'`; jmap -dump:format=b,file=/data/dump/${JAR_NAME}.dump
                ${pid}

大致意思是在容器銷燬前通過jmap命令收集dump到指定目錄。

有兩點需要特別說明:

1.注意這個目錄需要做持久化,而且要及時清理減少磁盤佔用,因爲日常的發佈也會觸發preStop;

2.另一個需要注意的是終止寬限期-terminationGracePeriodSeconds需要調整,給jmap預留充分的時間保留現場,也不能太長,調長的副作用是滾動發佈會變慢。

推薦閱讀

https://kubernetes.io/zh-cn/docs/concepts/containers/container-lifecycle-hooks/

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章