一、引出問題
生產項目是用k8s部署的,最近經常遇到啟動時注冊不到nacos(查找nacos的host地址找不到),或者運行的好好的,突然也連不上nacos了(同樣是查找nacos的host地址找不到)。
問題定位到,由于網絡或其他問題,導致pod之間的網絡出現了問題,導致根據服務名查找pod失敗。
解決方案:考慮到幾乎無法讓pod自行連接上nacos了,所以考慮應用加上actuator健康檢查,k8s加上探針,如果應用健康檢查不通過,就重啟pod。
二、解決方案
1、使用actuator健康檢查
引入actuator健康檢查,如果nacos注冊失敗,就重啟容器
。
因為k8s已經支持了健康檢查服務,每隔一段時間就會進行健康檢查。
這里用到了spring-boot-starter-actuator
。
啟動健康檢查之后,訪問/actuator/health
,會提示UP,如果nacos宕機或者網絡連接不上,會提示DOWN,并且返回碼是503:
如果nacos正常的話,status是UP,并且返回碼是200:
2、項目啟動時判斷nacos是否正常連接
項目啟動時,如果nacos連接不上,就會在main方法拋出異常:
根源就是調用nacos -server端的api時發生的異常,但是如果捕捉這個異常,就會對業務代碼侵入性較強。
好在如果發生了這個異常,就會中斷springboot項目的啟動,用健康檢查就非常的合適,此時健康檢查的接口都調用不到。
3、k8s設置探針
參考文檔:https://www.cnblogs.com/shenyuanhaojie/p/16439958.html
官方文檔:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
目前的k8s健康檢查,http請求只能根據響應碼來判斷,如果想通過json體來判斷,恐怕需要自定義一個接口了(或者用正則進行解析)。
但是springboot自帶的actuator,是可以根據服務的健康狀態返回不同的響應碼的。
以下是大模型 給的結果,沒驗證過:
所以,要加上restartPolicy
配置:
在Kubernetes(簡稱K8s)中,Pod的重啟策略定義了當容器失敗時kubelet如何處理。有三種主要的重啟策略:
Always
:
這是默認的重啟策略。如果設置了為“Always”,那么無論容器停止運行的原因是什么(無論是正常退出還是異常終止),kubelet都會自動重啟該容器。這意味著只要Pod尚存在,即使容器連續出錯,kubelet也會不斷地嘗試重啟容器。
OnFailure:
如果設置為“OnFailure”,則只有當容器以非0狀態退出碼結束時,kubelet才會嘗試重啟該容器。若容器正常退出(即退出碼為0),kubelet將不會進行重啟操作。
Never:
當設置為“Never”時,kubelet將不會對任何原因導致停止運行的容器進行重啟。一旦容器停止,它將保持停止狀態,直到手動干預或關聯的控制器采取行動。
OnCrash(崩潰時重啟)
該策略主要用于DaemonSet中的Pod。只有在節點重啟或Pod崩潰后,才會觸發Pod的重啟。
綜上所述,每個Pod中的所有容器共享相同的重啟策略,由Pod的spec.restartPolicy字段指定。需要注意的是,當Pod被控制器(如Deployment、StatefulSet等)管理時,即使Pod未明確指定重啟策略,控制器也會根據自身邏輯控制Pod副本的重啟行為。