新聞中心
Kubernetes實踐之優(yōu)雅終止
作者:I am roc 2021-06-04 10:52:51
云計算 Pod 銷毀時,會停止容器內(nèi)的進(jìn)程,通常在停止的過程中我們需要執(zhí)行一些善后邏輯,比如等待存量請求處理完以避免連接中斷,或通知相關(guān)依賴進(jìn)行清理等,從而實現(xiàn)優(yōu)雅終止目的。本文介紹在 Kubernetes 場景下,實現(xiàn)容器優(yōu)雅終止的最佳實踐。

創(chuàng)新互聯(lián)是一家專業(yè)提供天河企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站制作、做網(wǎng)站、H5頁面制作、小程序制作等業(yè)務(wù)。10年已為天河眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。
[[403677]]
本文轉(zhuǎn)載自微信公眾號「云原生知識宇宙」,作者I am roc。轉(zhuǎn)載本文請聯(lián)系云原生知識宇宙公眾號。
概述
Pod 銷毀時,會停止容器內(nèi)的進(jìn)程,通常在停止的過程中我們需要執(zhí)行一些善后邏輯,比如等待存量請求處理完以避免連接中斷,或通知相關(guān)依賴進(jìn)行清理等,從而實現(xiàn)優(yōu)雅終止目的。本文介紹在 Kubernetes 場景下,實現(xiàn)容器優(yōu)雅終止的最佳實踐。
容器終止流程
我們先了解下容器在 Kubernetes 環(huán)境中的終止流程:
- Pod 被刪除,狀態(tài)置為 Terminating。
- kube-proxy 更新轉(zhuǎn)發(fā)規(guī)則,將 Pod 從 service 的 endpoint 列表中摘除掉,新的流量不再轉(zhuǎn)發(fā)到該 Pod。
- 如果 Pod 配置了 preStop Hook ,將會執(zhí)行。
- kubelet 對 Pod 中各個 container 發(fā)送 SIGTERM 信號以通知容器進(jìn)程開始優(yōu)雅停止。
- 等待容器進(jìn)程完全停止,如果在 terminationGracePeriodSeconds 內(nèi) (默認(rèn) 30s) 還未完全停止,就發(fā)送 SIGKILL 信號強(qiáng)制殺死進(jìn)程。
- 所有容器進(jìn)程終止,清理 Pod 資源。
業(yè)務(wù)代碼處理 SIGTERM 信號
要實現(xiàn)優(yōu)雅終止,務(wù)必在業(yè)務(wù)代碼里面處理下 SIGTERM 信號,參考 處理 SIGTERM 代碼示例 ) 。
別讓 shell 導(dǎo)致收不到 SIGTERM 信號
如果容器啟動入口使用了腳本 (如 CMD ["/start.sh"]),業(yè)務(wù)進(jìn)程就成了 shell 的子進(jìn)程,在 Pod 停止時業(yè)務(wù)進(jìn)程可能收不到 SIGTERM 信號,因為 shell 不會自動傳遞信號給子進(jìn)程。更詳細(xì)解釋請參考 為什么我的容器收不到 SIGTERM 信號 ?
如果解決?請參考 在 SHELL 中傳遞信號。
合理使用 preStop Hook
若你的業(yè)務(wù)代碼中沒有處理 SIGTERM 信號,或者你無法控制使用的第三方庫或系統(tǒng)來增加優(yōu)雅終止的邏輯,也可以嘗試為 Pod 配置下 preStop,在這里面實現(xiàn)優(yōu)雅終止的邏輯,示例:
- lifecycle:
- preStop:
- exec:
- command:
- - /clean.sh
參考 Kubernetes API 文檔
在某些極端情況下,Pod 被刪除的一小段時間內(nèi),仍然可能有新連接被轉(zhuǎn)發(fā)過來,因為 kubelet 與 kube-proxy 同時 watch 到 pod 被刪除,kubelet 有可能在 kube-proxy 同步完規(guī)則前就已經(jīng)停止容器了,這時可能導(dǎo)致一些新的連接被轉(zhuǎn)發(fā)到正在刪除的 Pod,而通常情況下,當(dāng)應(yīng)用受到 SIGTERM 后都不再接受新連接,只保持存量連接繼續(xù)處理,所以就可能導(dǎo)致 Pod 刪除的瞬間部分請求失敗。
這種情況下,我們也可以利用 preStop 先 sleep 一小下,等待 kube-proxy 完成規(guī)則同步再開始停止容器內(nèi)進(jìn)程:
- lifecycle:
- preStop:
- exec:
- command:
- - sleep
- - 5s
調(diào)整優(yōu)雅時長
如果需要的優(yōu)雅終止時間比較長 (preStop + 業(yè)務(wù)進(jìn)程停止可能超過 30s),可根據(jù)實際情況自定義 terminationGracePeriodSeconds,避免過早的被 SIGKILL 殺死,示例:
參考資料
處理 SIGTERM 代碼示例: https://imroc.cc/k8s/ref/code-example-of-handle-sigterm/
為什么我的容器收不到 SIGTERM 信號: https://imroc.cc/k8s/faq/why-cannot-receive-sigterm/
在 SHELL 中傳遞信號: https://imroc.cc/k8s/trick/propagating-signals-in-shell/
網(wǎng)站欄目:Kubernetes實踐之優(yōu)雅終止
標(biāo)題網(wǎng)址:http://www.fisionsoft.com.cn/article/dheedhs.html


咨詢
建站咨詢
