【问题标题】:Docker Run Script to catch interruption signalDocker Run Script 捕捉中断信号
【发布时间】:2018-05-09 16:20:36
【问题描述】:

我有一个启动多个容器的 docker-compose.yml。 其中之一使用 Dockerimage 文件来安装该容器中所需的一切。

我想添加一个每次等待中断信号 0、9 和 137 时运行的脚本。

现在,我正在尝试将脚本作为 Dockerimage 文件中的入口点运行,但似乎不起作用。

这是 Dockerimage 文件的内容:

RUN apt-get update && [...]
WORKDIR "/application"
ENTRYPOINT ["/bin/bash", "-c", "/application/scripts/cl.sh"] 

我做错了吗?需要用下面的命令重建容器吗?

docker-compose build

这是 bash 脚本 cl.sh 的内容

#!/bin/bash

echo "HELLO HELLO HELLO HELLO"

trap 'echo "Exiting with a 137 signal."' 137 0 9

目前脚本的唯一目的是测试一切是否正常。

【问题讨论】:

  • 请附上minimal reproducible example,包括你用来发送信号的shell脚本和命令/方法。问题很可能是您作为 pid 1 包含的额外 /bin/bash 进程,但我想在发布答案之前对此进行测试。
  • @BMitch 我按原样添加了脚本内容。如您所见,它只是为了测试它与 Docker 系统的连接是否正常工作。
  • 您的容器是否仍在运行以捕获信号?定义陷阱后,您的脚本会立即结束,这将结束容器。
  • 我没有测试你的整个例子,但是关于你的 Dockerfile 的 ENTRYPOINT 命令,bash 选项 -c 是题外话,应该删除,因为这个选项专用于传递内联代码到 bash,不用于运行外部脚本。
  • 酷!现在正在工作,但正如您所说,容器在脚本运行时停止。知道如何捕捉中断信号吗?这个想法是在容器停止之前运行备份。

标签: bash docker docker-compose dockerfile


【解决方案1】:

是的,可以实现您想要的,但在展示相应的代码之前,我必须评论您的问题代码,其中包含一些问题:

  • trap 'echo "Exiting with a 137 signal."' 137 0 9 行不正确,因为 137 不是有效的信号编号(参见例如Wikipedia article on signals)。

    也许你刚刚遇到了 137,因为它是 exit code 对应于 signal 9(假设 137 = 128 + 9,请参阅 this appendix in the bash doc.

  • 0 (EXIT) 和 9 (KILL) 是有效的信号编号,但实际上最好只捕获 2 (INT) 和 15 (TERM),如 this SE/Unix answer 中所建议的那样。

    确实,虽然 INT 和 TERM 信号可用于“优雅终止”,但 KILL 信号意味着必须立即终止进程,如man trap 所述:

    为 SIGKILL 或 SIGSTOP 设置陷阱会产生未定义的结果。 [...] 捕获 SIGKILL 或 SIGSTOP 在语法上被一些历史实现所接受,但它没有效果。便携式 POSIX 应用程序无法尝试捕获这些信号。

  • 在入口点脚本的末尾设置陷阱是一个不好的策略,因为它在这个地方没有用。相反,我建议您定义一个清理函数(最后一条指令为 exit),然后在脚本开头设置此函数的陷阱,然后运行您的(非终止)应用程序。

因此有以下概念验证:

Dockerfile

FROM debian:latest
WORKDIR /app

COPY entrypoint.bash ./
ENTRYPOINT ["/bin/bash", "./entrypoint.bash"]

入口点.bash

#!/bin/bash

cleanup() {
    echo "Cleaning up..."
    exit
}

trap cleanup INT TERM

while :; do
    echo "Hello! ${SECONDS} secs elapsed..."
    sleep 1s
done

要测试它,你只需要运行:

$ docker build -t test-trap .
$ docker run -d --name=TEST-TRAP test-trap
  # wait a few seconds
$ docker stop TEST-TRAP
$ docker logs -f TEST-TRAP
Hello! 0 secs elapsed...
Hello! 1 secs elapsed...
Hello! 2 secs elapsed...
Hello! 3 secs elapsed...
Cleaning up...

【讨论】:

    猜你喜欢
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多