我的目录中有以下两个文件:
Dockerfile
FROM debian
WORKDIR /app
COPY start.sh /app/
CMD ["/app/start.sh"]
start.sh
(使用 chmod +x start.sh
的权限为 755)
#!/bin/bash
trap "echo SIGINT; exit" SIGINT
trap "echo SIGTERM; exit" SIGTERM
echo Starting script
sleep 100000
然后运行以下命令:
$ docker build . -t tmp
$ docker run --name tmp tmp
然后我期望按 Ctrl+C 会向程序发送 SIGINT,该程序会将 SIGINT 打印到屏幕然后退出,但这并没有发生。
我还尝试运行
$ docker stop tmp
,我希望它会向程序发送一个 SIGTERM,但之后检查 $ docker logs tmp
显示 SIGTERM 未被捕获。
为什么 bash 脚本没有捕获 SIGINT 和 SIGTERM?
实际上,只要您使用以下命令之一运行容器,您的
Dockerfile
和 start.sh
入口点脚本就可以通过 Ctrl+C 正常工作:
docker run --name tmp -it tmp
docker run --rm -it tmp
docker run --help
中所述:
--interactive
= -i
CLI 标志要求 保持 STDIN 打开,即使未连接--detach
= -d
CLI 标志)--tty
= -t
CLI 标志要求 分配伪 TTY为了完整起见,请注意,有几个相关问题可能会导致
docker stop
花费太多时间并“回退”到 docker kill
,这可能在 shell 入口点启动其他进程时出现:
exec
:exec prog arg1 arg2 ...
INT
/ TERM
,但不是 KILL
)非常重要;原因是 bash 在前台进程终止之前不会处理信号,在您的情况下是
sleep 10000
。你的陷阱确实有效,但你必须先等待 10000 秒。
你的解决办法是
#!/bin/bash
pid=
trap 'echo SIGINT; [[ $pid ]] && kill $pid; exit' SIGINT
trap 'echo SIGTERM; [[ $pid ]] && kill $pid; exit' SIGTERM
echo Starting script
sleep 10000 & pid=$!
wait
pid=
此外,您可能希望用捕获任何出口来替换捕获特定信号
trap 'echo EXIT; [[ $pid ]] && kill $pid; exit' EXIT
这些以及更多内容在 http://mywiki.wooledge.org/SignalTrap#When_is_the_signal_handled.3F
都有很好的解释CTRL+C 向在该控制台上运行的
docker
发送信号。docker exec -it <containerId> /bin/sh -c "pkill -INT -f 'start\.sh'"
或者在您的脚本中包含
echo "my PID: $$"
并发送
docker exec -it <containerId> /bin/sh -c "kill -INT <script pid>"
docker 中的某些 shell 实现可能会忽略该信号。 该脚本将正确响应
pkill -15
。请注意,指定的信号没有 SIG
前缀。
#!/bin/sh
trap "touch SIGINT.tmp; ls -l; exit" INT TERM
trap "echo 'really exiting'; exit" EXIT
echo Starting script
while true; do sleep 1; done
长
sleep
命令被短命令的无限循环所取代,因为 sleep
可能会忽略一些信号。
尝试使用以下脚本作为您的
ENTRIPOINT
:
#!/bin/bash
# Start the main process and save its PID
# Use exec to replace the shell script process with the main process
exec my_main_process &
pid=$!
# Trap the SIGTERM signal and forward it to the main process
trap 'kill -SIGTERM $pid; wait $pid' SIGTERM
# Wait for the main process to complete
wait $pidh
来源:https://www.linkedin.com/pulse/propagating-sigterm-signal-main-process-kubernetes-pod-chidambaram/