我在docker容器中运行了一个cronjob,它检查所有服务是否按预期运行。如果这个cronjob确定存在问题我想停止docker容器(从内部......)
不幸的是exit
只是停止了我的cronjob脚本
答案 0 :(得分:7)
基本上,您需要PID 1才能退出以停止容器。
我最初认为kill -s SIGKILL 1
会起作用,但PID 1受到保护,所以它没有。
正如@Thomasleveil所建议的那样,您可以将trap "exit" SIGINT SIGTERM
等代码添加到PID 1脚本中,这意味着当发送kill -s SIGINT 1
时,该过程将退出。我稍微倾向于使用这个方法(直接杀死子进程),因为它为父进程提供了清理机会,并且父进程应该能够在没有awk的情况下找到子进程的PID。 / p>
但是,如果你正在运行多个进程,你应该考虑使用supervisord或runit之类的东西。
答案 1 :(得分:2)
我遇到了同样的问题,并使用docker的healthcheck功能解决了这个问题。
您可以在heahthcheck.sh
之类的文件中添加检查以验证服务。然后在您的Dockerfile
后面加上以下内容:
# Healthcheck
COPY healthcheck.sh /
RUN chmod +x /healthcheck.sh
HEALTHCHECK --interval=10s --retries=5 CMD /healthcheck.sh
这可确保docker通过在指定间隔内运行脚本来检查容器的运行状况,并且如果该脚本连续5次失败,则将状态标记为不正常。
现在,要在状态不正常的情况下重新启动容器,可以像这样使用autoheal:
docker run -d \
--name autoheal \
--restart=always \
-e AUTOHEAL_CONTAINER_LABEL=all \
-v /var/run/docker.sock:/var/run/docker.sock \
willfarrell/autoheal
这将在每次容器状态不正常时重新启动容器。
答案 2 :(得分:0)
我最近不得不弄清楚这一点。经过无奈之后,我的想法是这样的:
在您的dockerfile中,指定一个ENTRYPOINT:
ENTRYPOINT ["/entrypoint.sh"]
然后,提供这样的脚本。除了调用您的应用程序外,它不需要执行任何其他操作。随时向脚本添加其他设置,但是请注意,如果脚本在调用您的应用程序后执行任何操作,则可能会掩盖您应用程序的返回代码。如果与您相关,请确保脚本捕获返回码并将其作为自己的返回码传播出去。
注意:请勿使用exec
来调用您的应用程序!
结果将是PID 1属于entrypoint.sh,而您的应用程序将具有其他一些PID。矿山倾向于降落在PID 9或10上。
然后,当您需要终止应用程序时,只需确定其PID并调用kill -SIGKILL $PID
或pkill -SIGKILL yourapp
。您的过程不是PID 1,将接收到该信号并立即退出。您的entrypoint.sh
将立即退出,因为这是您设计退出流程后要执行的操作。
答案 3 :(得分:0)
受@JakeRobb启发: 您可以使用以下命令执行Docker:
/bin/bash -c "while true; do sleep infinity || exit 0; done"
这将对低于1的PID执行睡眠。一旦杀死它,循环将退出。为此,在docker内部使用:
pkill -f sleep
答案 4 :(得分:0)
我的自杀示例/usr/local/bin/docker-entrypoint.sh
#!/bin/sh
#
# Following guard prevents to stuck containers in DIND GitLab Runner
# If container still works in 300 seconds, this will kill yourself
THE_PID=$$
if [ $THE_PID -eq 1 ]; then
# Docker does not allow kill process 1, so restart as child process
/usr/local/bin/docker-entrypoint.sh
exit $?
fi
(sleep 300; echo "Killing process: $THE_PID"; kill -9 $THE_PID) &
YOUR_SCRIPT_TEXT....
答案 5 :(得分:-1)
我杀死了“阻塞进程”,即您的docker正在运行的主要进程;就像这样(我在这种情况下,docker正在运行sleep infinity命令以进行演示)。
ps -afx | grep sleep | awk'{print $ 1}'| xargs杀死-9
答案 6 :(得分:-3)
我试图杀死进程1但没有成功。
使用shutdown -h now
尝试@ zero323的评论。它工作正常(对不起,我不能直接投票,因为它不在答案列表中)。