我试图理解为什么我的 Docker 容器没有正常停止并且只是超时。容器正在运行crond:
FROM alpine:latest
ADD crontab /etc/crontabs/root
RUN chmod 0644 /etc/crontabs/root
CMD ["crond", "-f"]
Run Code Online (Sandbox Code Playgroud)
该crontab文件是:
* * * * * echo 'Working'
# this empty line required by cron
Run Code Online (Sandbox Code Playgroud)
内置docker build . -t periodic:latest
并运行docker run --rm --name periodic periodic:latest
这一切都很好,但是当我尝试docker stop periodic从另一个终端进行操作时,它不会优雅地停止,超时会突然终止。就像crond没有响应 SIGTERM 一样。
crond肯定是PID 1
/ # ps
PID USER TIME COMMAND
1 root 0:00 crond -f
6 root 0:00 ash
11 root 0:00 ps
Run Code Online (Sandbox Code Playgroud)
但是,如果我这样做:
docker run -it --rm --name shell alpine:latest ash在
docker exec -it shell crond -f另一个终端中,我可以使用crondSIGTERM 从第一个 shell 中终止,所以我知道可以使用 SIGTERM 停止它。
谢谢你的帮助。
向容器添加一个 init 进程(init: truein docker-compose.yml)解决了这个问题。
编辑:我阅读了此https://blog.thesparktree.com/cron-in-docker以了解在 Docker 中运行 cron 的问题和解决方案。从这篇文章:
\n“最后,当你\xe2\x80\x99一直在玩的时候,你可能已经注意到\xe2\x80\x99很难杀死运行cron的容器。你可能必须使用dockerkill或docker-composekill来终止容器,而不是使用 ctrl + C 或 docker stop。
\n不幸的是,在前台运行时,cron 实现似乎并不总是正确处理 SIGINT。
\n在研究了几种替代方案后,唯一可行的解决方案似乎是使用进程管理器(如 tini 或 s6-overlay)。由于 tini 已合并到 Docker 1.13 中,从技术上讲,您可以通过将 --init 传递给 docker run 命令来透明地使用它。在实践中,您通常可以\xe2\x80\x99t,因为您的集群管理器\xe2\x80\x99t不支持它。”
\n自从我最初的帖子和答案以来,我已经迁移到 Kubernetes,所以init在 docker-compose.yml 中将不起作用。我的容器基于 Debian Buster,所以我现在已经安装tini在 Dockerfile 中,并将 ENTRYPOINT 更改为["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"](我的 entrypoint.sh 最终做到了exec cron -f)
| 归档时间: |
|
| 查看次数: |
1292 次 |
| 最近记录: |