建议阅读:

Docker stop 不能停止容器

docker stop 主流程

1,docker 通过 containerd 向容器主进程发送 SIGTERM(终止进程)信号后等待一段时间后(默认是10s,可以通过-t 参数来修改),如果从containerd 收到了容器退出消息,那么容器退出成功。 2,如果超过等待的时间之后,还是没收到容器退出的消息,那么docker 将使用docker kill方式试图终止容器。

但是对于容器来说,init 系统进程并不是必须的,所以当我们停止容器的时候,docker 通过 containerd 向容器Pid 为 1 的进程发送 SIGTERM信号并不一定会被采纳。其实可以分为以下两种情况来说明:

1,如果 PID==1 的进程是 init 进程:

那么 PID==1 会将 SIGTERM 信号转发给子进程,然后子进程开始关闭,最后容器终止

2,如果PID==1 的进程不是 init 进程:

那么容器中的应用进程(Dockerfile 中的 ENTRYPOINT 或 CMD 指令指定的应用)的 PId 就是 1,应用进程直接负责响应 SIGTERM 信号。这个时候又分为两种情况

1,应用不处理 SIGTERM 信号:

 应用没有监听 SIGTERM 信号,或者应用中没有事先处理 SIGTERM 信号的逻辑,应用就不会停止,容器也不会正常终止,会被 调用 docker kill 方式杀死(我们的程序目前就是这种)

2,容器停止时间很长:

运行命令 docker stop 之后,docker 会默认等待 10S(默认值,可以修改 docker stop -t 指令),如果 10s后容器还没有终止,docker 就会绕过容器应用直接向内核发送 SIGKILL,内核强行杀死应用,从而终止容器。

docker kill主流程

1,docker 引擎通过containerd 使用 SIGKILL 发向容器主进程,等待一段时间后,如果从containerd收到容器退出消息,那么容器kill成功 2,在上一步中如果等待超时,Docker引擎将跳过 containerd 自己亲自动手通过kill系统调用向容器主进程发送 SIGKILL 信号。如果此时 kill 系统调用返回主进程不存在,那么 Docker Kill 成功。否则引擎将一直死等到 containerd 通过引擎,容器退出.