我希望容器中有一个自定义bash脚本,在容器停止之前自动调用(docker stop
或ctrl + 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
我的代码有什么问题?
1条答案
按热度按时间hgtggwj01#
您的帮助和意见引导我走上了正确的方向,我再次浏览了官方文档here,here和here,终于找到了问题所在。
问题如下:
我的
entrypoint.sh
脚本使容器保持活动状态,并在最后执行了以下命令:-D
选项在NOT detach模式下运行ssh守护进程,sshd
不会成为守护进程。实际上,这是我的意图,这是我保持容器活动的方式。但是这个前台进程阻止了
trap
命令的正确执行。我改变了启动sshd
应用程序的方式,现在它作为一个正常的后台进程运行。然后,我添加了以下命令来保持Docker容器的活动状态(这是推荐的最佳实践):
当然,同样的问题也出现了。
Tail
作为前台进程运行,trap
命令不能完成它的工作。要保持容器的活动状态并让
entrypoint.sh
作为外来进程在Docker中运行,唯一的方法如下:这样,
trap
命令就可以正常工作,并且我的bash函数在处理SIGINT
等信号时也可以正常运行。但老实说,我不喜欢这个解决方案。这个使用
sleep
的无休止循环看起来很丑,但我目前不知道如何以一种好的方式管理它:(但这是另一个问题,不属于这个线程(但可能是伟大的,如果你能建议我一个更好的解决方案)。