正常情況下,執(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強(qiáng)制殺掉進(jìn)程

至于這里為什么會等待30s,原因如下: k8s pod在結(jié)束前可能需要執(zhí)行一些命令,這些命令可以設(shè)置在preStop中進(jìn)行設(shè)置,在刪除pod的時候,preStop Hook和SIGTERM 信號并行發(fā)生,但是Kubernetes 不會等待 preStop Hook 完成,所以這里需要設(shè)置一個等待時間讓preStop執(zhí)行完成之后,在刪除pod,這個等待時間就是通過terminationGracePeriodSeconds進(jìn)行設(shè)置的.
但是我們的pod里并沒有設(shè)置preStop,還是等待了30s pod才徹底被刪除
所以這里的問題可能是第1步中,kill 1并沒有將進(jìn)程殺掉, 也就是說進(jìn)程并沒有響應(yīng)SIGTERM信號
為什么會出現(xiàn)這種情況呢, 進(jìn)入到容器中看下具體的進(jì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
可以看到有兩個進(jìn)程, 其中1為主進(jìn)程, 7為1的子進(jìn)程, start.sh內(nèi)容如下:
#!/usr/bin/env bash python3 /server.py
通過執(zhí)行shell腳本拉起真正的業(yè)務(wù)進(jìn)程, 而且以阻塞方式運(yùn)行, 刪除pod時, 發(fā)送的SIGTERM信號不會有任何響應(yīng), 因?yàn)閭鬟f不到子進(jìn)程7, 無法結(jié)束子進(jìn)程, 進(jìn)而導(dǎo)致pod無法結(jié)束.
這里可能會有這樣的疑問, 為什么不直接啟動業(yè)務(wù)進(jìn)程呢? 這是因?yàn)橛行﹫鼍跋? 在啟動業(yè)務(wù)進(jìn)程之前, 需要進(jìn)行一些初始化操作, 又不想或者不能通過init-container來完成, 只能通過啟動腳本去做, 啟動腳本初始化結(jié)束之后, 再將業(yè)務(wù)進(jìn)程拉起.
如何避免這類問題
盡量直接啟動業(yè)務(wù)進(jìn)程, 不要依賴進(jìn)程拉起業(yè)務(wù)進(jìn)程, 初始化操作盡量通過init-container來完成
在啟動腳本里捕獲SIGTERM, 并將其傳遞到子進(jìn)程
#!/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傳遞到子進(jìn)程, 讓pod快速結(jié)束
鏈接:https://juejin.cn/post/7314804357697945637
審核編輯:劉清
-
Shell
+關(guān)注
關(guān)注
1文章
375瀏覽量
25381
原文標(biāo)題:[Kubernetes] 為什么有時會出現(xiàn)刪除POD之后,需要等待一段時間才能被刪掉?
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
STM8串口工作一段時間后出現(xiàn)通訊異常的原因?
esp32使用esp_http_client時過了一段時間就會出現(xiàn)報錯,為什么?
ADS1220運(yùn)行一段時間后出現(xiàn)ADC = -1 的錯值,怎么解決?
ADS1243 DRDY有時會出現(xiàn)總是高電平,為什么?
ADS1013采集運(yùn)放輸出數(shù)據(jù),一段時間后變的很低是為什么?
使用stm32的spi讀取ads1256數(shù)據(jù),ads1256正常輸出數(shù)據(jù)一段時間后總會出現(xiàn)異常默認(rèn)設(shè)置,為什么?
ADS8328兩路輸入端在配置成自動或手動都會出現(xiàn)一段時間后通道翻轉(zhuǎn)的情況,為什么?
LSM6DSR工作一段時間后就算靜止不動也會出現(xiàn)Y軸數(shù)據(jù)偏移,是什么原因?qū)е碌模?/a>
為什么enc28j60+lwip的例程有時ping一段時間后延時很大?
uCOS III+lwIP運(yùn)行一段時間后無法重連是怎么回事?
FreeRtos系統(tǒng)運(yùn)行一段時間后跑死了是什么原因?
CH579有時會出現(xiàn)拔了網(wǎng)線,狀態(tài)燈常亮怎么解決?
為什么TSC測量在退出stop模式后需要等待一段時間才能正常讀數(shù)呢
Arduino 接MPU6050 9250使用IIC通訊,輸出數(shù)據(jù)一段時間后死機(jī)卡死的問題解決
[Kubernetes]為什么有時會出現(xiàn)刪除POD后要等一段時間才能被刪掉
評論