docker stop [容器ID] 时,Docker 守护进程会先向容器主进程(PID 1)发送 SIGTERM 信号。SIGTERM 信号后,应该自行进行清理操作,例如关闭数据库连接、停止监听端口等。SIGKILL 信号,强制结束容器进程。SIGTERM 信号做出响应。要是主进程是一个不会处理信号的脚本或者二进制文件,就需要通过配置来实现信号的监听,比如使用 trap 命令。init 系统(例如 tini),以此来管理子进程的信号传递,防止出现僵尸进程。| 指令 | 信号类型 | 效果 | 适用情形 |
|---|---|---|---|
docker stop |
SIGTERM |
先尝试优雅关闭,超时时强制终止 | 正常的服务停止 |
docker kill |
SIGKILL |
直接强制终止进程 | 应用无响应时的紧急终止 |
不论是什么类型的应用,都会希望在服务停止前能够收到停止通知,有一定的时间做退出前的释放资源、关闭连接、不再接收外部请求等工作。比如你的应用正在处理HTTP请求,你希望在停止前能完成所有未完成的请求;如果你的应用正在写入文件,你也许希望在停止容器前能够正确的刷新数据到磁盘并关闭文件。
要了解应用优雅停止方法,我们先回顾一下与容器相关的Linux常见信号。
信号是一种进程间通信的形式。一个信号就是内核发送给进程的一个消息,告诉进程发生了某种事件。进程需要为自己感兴趣的信号注册处理程序,举例:
使用 kill -l 命令会显示Linux支持的信号列表。其中编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。
下面对常用的信号进行说明: