Docker 停止休眠 bash 脚本

Docker stop sleeping bash script

我有 bash 作为 docker 入口点运行的脚本。

此脚本执行一些操作然后休眠。

我需要能够在发出 docker stop 命令时优雅地停止此脚本。 AFAIK docker 向进程 1.

发送 SIGTERM 信号

所以我创建了 bash 脚本来响应 SIGTERM

它在没有 docker 的情况下工作正常,我可以启动它,发出 kill -TERM <pid> 并且它优雅地停止了脚本。不幸的是,它在 docker.

中不起作用

Docker 文件:

FROM ubuntu:20.04
WORKDIR /root
COPY test.sh .
CMD ./test.sh

test.sh:

#!/bin/sh
trap 'echo TERM; exit' TERM

sleep 1 &
while wait $!
do
    sleep 1 &
done

我应该如何修改脚本或 Dockerfile 以允许 docker 正常停止工作?

请注意,我不允许将 -it 参数传递给 docker run

我建议你试试 docker kill --signal=SIGTERM <CONTAINER_ID>

请告诉我它是否有效。

问题来自 shell 形式 CMD 指令:CMD ./test.sh.

在这种情况下,命令使用 /bin/sh -c shell 执行。所以 /bin/sh 作为 PID 1 运行,然后分叉 test.shPID 1/bin/sh -c ./test.sh。结果 SIGTERM 信号被发送到 PID 1 并且永远不会到达 test.sh.

要更改此设置,您必须使用 exec 表单CMD ["./test.sh"]。在这种情况下,将在没有 shell 的情况下执行命令 。所以信号会到达你的脚本。

FROM ubuntu:20.04
WORKDIR /root
COPY test.sh .
CMD ["./test.sh"]

运行 杀.

# run
docker run -d --name trap trap:latest
# send the signal
docker kill --signal=TERM trap
# check if the signal has been received
docker logs trap
# TERM

请注意,如果您的脚本恰好生成子进程,您可能会在 docker 退出时留下孤儿进程。尝试 运行 和 --init 标志,如 docker run --init ...,内置 docker-init 可执行文件 tini 将假定 pid 1 和确保所有子进程(例如您的睡眠示例)将在退出时相应地终止。