如何利用termination GracePeriodSeconds 優雅地關閉你的服務


當涉及到分佈式系統,處理故障是關鍵。Kubernetes經過利用能夠監視系統狀態並從新啓動已中止執行的服務的控制器(controllers)來解決這個問題。另外一方面,Kubernetes一般能夠強制終止您的應用程序,做爲系統正常運行的一部分。html

在容器出現以前,大多數應用運行在虛擬機或者物理機上。若是應用程序崩潰,啓動替換程序須要很長時間。若是您只有一臺或兩臺機器來運行應用程序,那麼這種恢復時間是不可接受的。nginx

相反,在崩潰時使用進程級監控來從新啓動應用程序變得很常見。若是應用程序崩潰,監視進程能夠捕獲退出代碼並當即從新啓動應用程序。數據庫

隨着像Kubernetes這樣的系統的出現,再也不須要進程監控系統,由於Kubernetes能夠處理重啓崩潰的應用程序。Kubernetes使用事件循環來確保容器和節點等資源是健康的。這意味着您再也不須要手動運行這些監視進程。 
若是資源未經過健康檢查,Kubernetes會自動啓動一個替代品。api

Kubernetes終止生命週期

Kubernetes不只能夠監控崩潰應用程序,它還能夠建立更多應用程序副本,以便在多臺計算機上運行,更新應用程序,甚至能夠同時運行多個版本的應用程序!微信

這意味着Kubernetes能夠終止一個徹底健康的容器有不少緣由。若是您使用滾動更新更新部署,Kubernetes會在啓動新pod時慢慢終止舊pod。若是drain一個節點,Kubernetes將終止該節點上的全部pod。若是節點資源不足,Kubernetes將終止pod以釋放這些資源網絡

您的應用程序要優雅地處理終止是相當重要的,能夠最終用戶受到的影響最小,而且恢復時間儘量快!架構

實際上,這意味着您的應用程序須要處理SIGTERM消息並在收到它時開始關閉。 
這意味着保存全部須要保存的數據,關閉網絡鏈接,完成剩下的任何工做以及其餘相似任務。併發

一旦Kubernetes決定終止您的Pod,就會發生一系列事件。 
讓咱們看看Kubernetes終止生命週期的每一步。負載均衡

1 - K8S 啓動新POD。

此時,新的POD等待啓動分佈式

2 - K8S等待新POD進入Ready(Running) 狀態。

此時,pod狀態爲Running。

3 - K8S建立Endpoint。

此時,k8s建立endpoint,將新服務歸入負載均衡。

4 - Pod設置爲」Terminating」狀態,並從全部服務的Endpoints列表中刪除。

此時,Pod中止得到新的流量。但在Pod中運行的容器不會受到影響。

5 - preStop Hook被執行

preStop Hook是一個發送到Pod中的容器特殊命令或Http請求。

若是您的應用程序在接收SIGTERM時沒有正常關閉,您可使用preStop Hook來觸發正常關閉。 
接收SIGTERM時大多數程序都會正常關閉,但若是您使用的是第三方代碼或管理的系統沒法控制,則preStop Hook是在不修改應用程序的狀況下觸發正常關閉的好方法。

6 - SIGTERM信號被髮送到Pod

此時,Kubernetes將向pod中的容器發送SIGTERM信號。這個信號讓容器知道它們很快就會關閉。

您的代碼應該監聽此事件並在此時開始乾淨利落關閉。這可能包括中止任何長期鏈接(如數據庫鏈接或WebSocket流),保存當前狀態或其它相似的事情。

即便您使用preStop Hook,若是您發送SIGTERM信號,測試應用程序會發生什麼狀況也很重要,以確保您對生產環境並不感到驚訝!

7 - Kubernetes等待優雅的終止

此時,Kubernetes等待指定的時間稱爲優雅終止寬限期。默認狀況下,這是30秒。值得注意的是,這與preStop Hook和SIGTERM信號並行發生。Kubernetes不會等待preStop Hook完成。

若是你的應用程序完成關閉並在terminationGracePeriod完成以前退出,Kubernetes會當即進入下一步。

若是您的Pod一般須要超過30秒才能關閉,請確保增長優雅終止寬限期。您能夠經過在Pod YAML中設置terminationGracePeriodSeconds選項來實現。 
例如,要將其更改成60秒:

apiVersion: v1kind: Podmetadata: name: nginx namespace: defaultspec: containers: - name: nginx image: nginx terminationGracePeriodSeconds: 30

8 - SIGKILL信號被髮送到Pod,並刪除Pod

若是容器在優雅終止寬限期後仍在運行,則會發送SIGKILL信號並強制刪除。與此同時,全部的Kubernetes對象也會被清除。

結論

Kubernetes能夠出於各類緣由終止pod,並確保您的應用程序優雅地處理這些終止,這是建立穩定系統和提供出色用戶體驗的核心。

譯者注:

kubernetes文檔指出,有些步驟是同時執行的。所以有可能會致使該Pod仍然列在服務的Endpoints中並仍然接收流量,而它已經收到SIGTERM而且已經中止,所以負載均衡器上可能會有一些Http 504。目前解決這個問題可使用preStop Hook 在容器收到SIGTERM時sleep一段時間,以確終止期間的流量能夠正確處理。設置方式:

apiVersion: v1kind: Podmetadata: name: nginx namespace: defaultspec: containers: - name: nginx image: nginx lifecycle:  preStop:  exec:  command:  - sleep - 30 terminationGracePeriodSeconds: 60

特別說明: 
preStop Hook並不會影響SIGTERM的處理,所以有可能preStopHook尚未執行完就收到SIGKILL致使容器強制退出。所以若是preStop Hook設置了n秒,須要設置terminationGracePeriodSeconds爲terminationGracePeriodSeconds+n秒。

文章來源:https://blog.8mi.net/Kubernetes/88.html

推薦閱讀:

談談 Kubernetes 架構

什麼是高併發架構?

到底什麼是分佈式系統?

Kubernetes是什麼以及你爲何選擇它?


點擊【 在看 】,謝謝。

本文分享自微信公衆號 - kubernetes中文社區(kubernetes_cn)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索