如何确保可以终止由Docker入口点启动的进程?

时间:2019-04-12 08:55:27

标签: linux bash shell docker entry-point

我正在构建一个Docker映像,该映像将启动一个运行时间较长的Java进程。我想确保它可以与容器一起杀死(例如,通过使用Ctrl + C),但仍然可以执行清理操作。

如果我在入口点使用exec java -jar,它会按预期工作。 如果我只是执行java -jar,则无法终止该进程。

但是exec会使容器即使成功也退出,如果此命令不是入口点中的最后一个命令,则这是一个问题。例如,如果进行了一些文件转换或清除,将不会执行该文件:

exec java -jar "./lib/Saxon-HE-${SAXON_VER}.jar" -s:"$json_xml" -xsl:"$STYLESHEET" base-uri="$base"
rm "$json_xml"

我认为解释是,使用exec的过程(在这种情况下为java)变为PID = 1并接收终止信号,而没有exec则获得了其他PID和没有收到信号,因此无法杀死。

所以我的问题有两个:

  • 是否有一种变通方法,可以像exec一样在不成功退出容器的情况下终止进程?
  • 即使进程被杀死/退出,我如何确保执行exec(在本例中为rm之后的清理工作?

3 个答案:

答案 0 :(得分:1)

您可以创建一个入口点bash脚本,以捕获CTRL-C信号,杀死(或正常停止?)Java进程,然后进行清理。

示例(未经测试):

#!/bin/bash

# trap ctrl-c and call ctrl_c()
trap ctrl_c INT

function ctrl_c() {
        echo "Trapped CTRL-C"
        # Do something here. Kill Java?
}

java -jar "./lib/Saxon-HE-${SAXON_VER}.jar" -s:"$json_xml" -xsl:"$STYLESHEET" base-uri="$base"

将其添加到您的docker映像中,并将其作为入口点

FROM java:8

ADD docker-entrypoint.sh /docker-entrypoint.sh

ENTRYPOINT ["/docker-entrypoint.sh"]

答案 1 :(得分:1)

我用蒂尼。这是参考文献link

答案 2 :(得分:1)

您可以仅构建另一个程序来管理java子进程和清理,例如使用相同的javagorust编写这样的程序。我确定这些语言都有适当的过程控制工具,并且您可以捕获CTRL-C和其他事件以停止内部子进程并进行清理。与搜索行为有限的工具相比,可能甚至会花费更少的时间。对于此类问题,甚至值得开源。