Docker容器重启慢?快来看看这些优雅终止方案(1),看完99%的人都学会了

2. 容器进程收不到 SIGTERM 信号?

如果容器中的进程没有收到 SIGTERM 信号,很有可能是因为应用进程不是 PID 1,PID 1 是 shell,而应用进程只是 shell 的子进程。而 shell 不具备 init 系统的功能,也就不会将操作系统的信号转发到子进程上,这也是容器中的应用没有收到 SIGTERM 信号的常见原因。

问题的根源就来自 Dockerfile,例如:

FROM alpine:3.7
COPY popcorn.sh .
RUN chmod +x popcorn.sh
ENTRYPOINT ./popcorn.sh

ENTRYPOINT 指令使用的是 shell 模式,这样 Docker 就会把应用放到 shell 中运行,因此 shell 是 PID 1。

解决方案有以下几种:

方案 1:使用 exec 模式的 ENTRYPOINT 指令

与其使用 shell 模式,不如使用 exec 模式,例如:

FROM alpine:3.7
COPY popcorn.sh .
RUN chmod +x popcorn.sh
ENTRYPOINT ["./popcorn.sh"]

这样 PID 1 就是 ./popcorn.sh,它将负责响应所有发送到容器的信号,至于 ./popcorn.sh 是否真的能捕捉到系统信号,那是另一回事。

举个例子,假设使用上面的 Dockerfile 来构建镜像,popcorn.sh 脚本每过一秒打印一次日期:

#!/bin/sh

while true
do
    date
    sleep 1
done

构建镜像并创建容器:

上一篇:docker十一:docker-DockerFile案例-CMD、ENTRYPOINT、ONBUILD


下一篇:使用 Dockerfile 自定义 Nginx 镜像