考慮以下,這在後臺運行sleep 60
,然後退出:當Docker容器的PID1退出時,其他進程會發生什麼?
$ cat run.sh
sleep 60&
ps
echo Goodbye!!!
$ docker run --rm -v $(pwd)/run.sh:/run.sh ubuntu:16.04 bash /run.sh
PID TTY TIME CMD
1 ? 00:00:00 bash
5 ? 00:00:00 sleep
6 ? 00:00:00 ps
Goodbye!!!
這將啓動一個泊塢的容器中,作爲bash
PID1。然後它叉/執行一個sleep
進程,然後bash
退出。當Docker容器死亡時,sleep
進程也死機。
我的問題是:什麼是sleep
進程被殺死的機制?我試圖在子進程中捕獲SIGTERM
,並且看起來沒有被絆倒。我的推測是,關閉容器正在使用的cgroup時,Docker或Linux內核正在發送SIGKILL
,但我在任何地方都沒有找到說明這一點的文檔。
編輯我來解釋最接近的是從baseimage-docker以下報價:
如果你的init進程是你的應用程序,那麼它很可能只是關閉本身,而不是所有的容器中的其他進程。內核然後會強行終止其他進程,而不是讓他們有機會正常關閉,可能導致文件損壞,臨時文件過時等。您真的想要優雅地關閉所有進程。
因此,至少根據這一點,暗示當容器退出時,內核將發送一個SIGKILL到所有剩餘的進程。但是我還是希望清楚它是如何決定這麼做的(即它是cgroups的一個特徵嗎?),理想情況下更權威的來源會更好。
這是可能的碼頭工人'runc'做清理,如果你[在主機PID命名空間運行(https://github.com/opencontainers/runc/blob/c4e0d94efacd6f6fb353a538cc01d10792cc3a35 /libcontainer/state_linux.go#L41-L45)。 – Matt
,內核確實發送了一個'SIGKILL'來終止進程。 – Matt
@Matt很高興知道。它是否成爲主機'init'進程收穫這些進程的責任,還是內核將它們從進程表本身中刪除? –