Docker Kill主要流程
1、Docker引擎通過containerd使用SIGKILL發(fā)向容器主進(jìn)程,等待一段時(shí)間后,如果從containerd收到容器退出消息,那么容器Kill成功。
2、在上一步中如果等待超時(shí),Docker引擎將跳過Containerd自己親自動(dòng)手通過kill系統(tǒng)調(diào)用向容器主進(jìn)程發(fā)送SIGKILL信號(hào)。如果此時(shí)kill系統(tǒng)調(diào)用返回主進(jìn)程不存在,那么Docker kill成功。否則引擎將一直死等到containerd通過引擎,容器退出。
當(dāng)出現(xiàn)問題時(shí)刻,宿主機(jī)上發(fā)現(xiàn)大量的stress進(jìn)程(實(shí)際是容器的進(jìn)程)處于D狀態(tài),而系統(tǒng)響應(yīng)變慢。問題可以這樣解釋:
1、Docker kill通過containerd間接向容器主進(jìn)程發(fā)送SIGKill信號(hào)以后,由于系統(tǒng)響應(yīng)慢,容器內(nèi)部子進(jìn)程(stress)處于D狀態(tài),那么在超時(shí)時(shí)間內(nèi)containerd沒有上報(bào)容器退出。Docker kill走到了直接發(fā)送Sigkill階段
2、在此階段前,容器內(nèi)部主進(jìn)程退出了,所以系統(tǒng)調(diào)用kill 發(fā)送SIGKILL很快就返回進(jìn)程不存在了。引擎認(rèn)為自己把容器殺死了,Docker kill成功返回了。
3、在一定時(shí)間后容器子進(jìn)程從D狀態(tài)中恢復(fù),它們退出了,containerd上報(bào)容器退出,引擎清理資源,此時(shí)Docker ps看到容器才是退出狀態(tài)。
容器主/子進(jìn)程處于D狀態(tài)
進(jìn)程D狀態(tài)表示進(jìn)程處于不可中斷睡眠狀態(tài),一般都是在等待IO資源。當(dāng)然有些時(shí)候如果系統(tǒng)IO出現(xiàn)問題,那么將有大量的進(jìn)程處于D狀態(tài)。在這種狀態(tài),信號(hào)是無法將進(jìn)程喚醒;只有等待進(jìn)程自己從D狀態(tài)中返回。而且在常規(guī)內(nèi)核中,如果某個(gè)進(jìn)程一直處于D狀態(tài),那么理論上除了重啟系統(tǒng)那么沒有什么方法或手段將它從D中接回。