正常情況下,執(zhí)行kubectl delete pod之后,pod一般會立即被刪除。但是偶爾會出現(xiàn)這樣一種情況,刪除pod之后,pod的狀態(tài)一直顯示為Terminating,需要等待一段時間才會被刪除,這是什么原因呢?
NAME READY STATUS RESTARTS AGE nginx 1/1 Terminating 0 4m34s
首先我們來了解一下,刪除pod時,k8s做了哪些操作
Typically, with this graceful termination of the pod, kubelet makes requests to the container runtime to attempt to stop the containers in the pod by first sending a TERM (aka. SIGTERM) signal, with a grace period timeout, to the main process in each container. The requests to stop the containers are processed by the container runtime asynchronously. There is no guarantee to the order of processing for these requests. Many container runtimes respect theSTOPSIGNALvalue defined in the container image and, if different, send the container image configured STOPSIGNAL instead of TERM. Once the grace period has expired, the KILL signal is sent to any remaining processes, and the Pod is then deleted from theAPI Server
上圖為k8s官方文檔上的說明,這一大段簡單概括起來就是如下兩步:
kubelet發(fā)送kill 1到pod
經(jīng)過terminationGracePeriodSeconds(一般為30s)之后,如果pod還沒被刪掉,則直接發(fā)送kill -9 1強制殺掉進程
至于這里為什么會等待30s,原因如下: k8s pod在結(jié)束前可能需要執(zhí)行一些命令,這些命令可以設置在preStop中進行設置,在刪除pod的時候,preStop Hook和SIGTERM 信號并行發(fā)生,但是Kubernetes 不會等待 preStop Hook 完成,所以這里需要設置一個等待時間讓preStop執(zhí)行完成之后,在刪除pod,這個等待時間就是通過terminationGracePeriodSeconds進行設置的.
但是我們的pod里并沒有設置preStop,還是等待了30s pod才徹底被刪除
所以這里的問題可能是第1步中,kill 1并沒有將進程殺掉, 也就是說進程并沒有響應SIGTERM信號
為什么會出現(xiàn)這種情況呢, 進入到容器中看下具體的進程:
UID PID PPID C STIME TTY TIME CMD root 1 0 0 08:58 ? 0000 bash /start.sh root 7 1 94 08:58 ? 0013 python3 /server.py
可以看到有兩個進程, 其中1為主進程, 7為1的子進程, start.sh內(nèi)容如下:
#!/usr/bin/env bash python3 /server.py
通過執(zhí)行shell腳本拉起真正的業(yè)務進程, 而且以阻塞方式運行, 刪除pod時, 發(fā)送的SIGTERM信號不會有任何響應, 因為傳遞不到子進程7, 無法結(jié)束子進程, 進而導致pod無法結(jié)束.
這里可能會有這樣的疑問, 為什么不直接啟動業(yè)務進程呢? 這是因為有些場景下, 在啟動業(yè)務進程之前, 需要進行一些初始化操作, 又不想或者不能通過init-container來完成, 只能通過啟動腳本去做, 啟動腳本初始化結(jié)束之后, 再將業(yè)務進程拉起.
如何避免這類問題
盡量直接啟動業(yè)務進程, 不要依賴進程拉起業(yè)務進程, 初始化操作盡量通過init-container來完成
在啟動腳本里捕獲SIGTERM, 并將其傳遞到子進程
#!/usr/bin/env bash exit_func() { pkill python3 exit } trap 'exit_func' SIGTERM python3 /server.py & while true do sleep 1 done
如上所示, 將start.sh調(diào)整一下, 這樣就能將SIGTERM傳遞到子進程, 讓pod快速結(jié)束
鏈接:https://juejin.cn/post/7314804357697945637
審核編輯:劉清
-
Shell
+關注
關注
1文章
365瀏覽量
23379
原文標題:[Kubernetes] 為什么有時會出現(xiàn)刪除POD之后,需要等待一段時間才能被刪掉?
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論