在docker停止容器之前自动调用容器中的脚本

pod7payv  于 2023-01-20  发布在  Docker
关注(0)|答案(1)|浏览(170)

我希望容器中有一个自定义bash脚本,在容器停止之前自动调用(docker stopctrl + c)。
根据this docker doc和多个StackOverflow线程,我需要在容器中捕获SIGTERM信号,然后在事件出现时运行我的自定义脚本。正如我所知,SIGTERM只能从PID 1的根进程使用。

我的Dockerfile的相关部分:

...
COPY container-scripts/entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]

我使用[]来定义entrypoint,正如我所知,这将直接运行我的脚本,而不需要/bin/sh -c Package 器(PID 1),并且当脚本最终执行另一个进程时,该进程将成为主进程,并将接收Docker停止信号。

入口点.sh:

...
# run the external bash script if it exists
BOOT_SCRIPT="/boot.sh"
if [ -f "$BOOT_SCRIPT" ]; then
    printf ">> executing the '%s' script\n" "$BOOT_SCRIPT"
    source "$BOOT_SCRIPT"
fi

# start something here
...

boot.sh被子容器用来执行子容器想要的其他东西。一切都很好,我的容器工作起来很有魅力。

子容器中的ps axu

PID   USER     TIME  COMMAND
    1 root      0:00 {entrypoint.sh} /bin/bash /entrypoint.sh
  134 root      0:25 /usr/lib/jvm/java-17-openjdk/bin/java -server -D...
  ...
  421 root      0:00 ps axu

在停止容器之前,我需要自动运行一些命令,所以我创建了一个shutdown.sh bash脚本。这个脚本工作正常,可以做我需要做的事情。但是我手动执行shutdown脚本的方式是:

$ docker exec -it my-container /bin/bash
# /shutdown.sh
# exit

$ docker container stop my-container

我想自动执行shutdown.sh脚本。
我尝试将以下内容添加到entrypoint.sh,但不起作用:

trap "echo 'hello SIGTERM'; source /shutdown.sh; exit" SIGTERM

我的代码有什么问题?

hgtggwj0

hgtggwj01#

您的帮助和意见引导我走上了正确的方向,我再次浏览了官方文档hereherehere,终于找到了问题所在。

问题如下:

我的entrypoint.sh脚本使容器保持活动状态,并在最后执行了以下命令:

# start the ssh server
ssh-keygen -A
/usr/sbin/sshd -D -e "$@"

-D选项在NOT detach模式下运行ssh守护进程,sshd不会成为守护进程。实际上,这是我的意图,这是我保持容器活动的方式。
但是这个前台进程阻止了trap命令的正确执行。我改变了启动sshd应用程序的方式,现在它作为一个正常的后台进程运行。
然后,我添加了以下命令来保持Docker容器的活动状态(这是推荐的最佳实践):

tail -f /dev/null

当然,同样的问题也出现了。Tail作为前台进程运行,trap命令不能完成它的工作。
要保持容器的活动状态并让entrypoint.sh作为外来进程在Docker中运行,唯一的方法如下:

while true; do
    sleep 1
done

这样,trap命令就可以正常工作,并且我的bash函数在处理SIGINT等信号时也可以正常运行。
但老实说,我不喜欢这个解决方案。这个使用sleep的无休止循环看起来很丑,但我目前不知道如何以一种好的方式管理它:(
但这是另一个问题,不属于这个线程(但可能是伟大的,如果你能建议我一个更好的解决方案)。

相关问题