Ott*_*tto 5 bash sleep sigkill sigint docker
案例:我们有一个运行 bash 脚本的 docker 容器,该脚本需要永远“阻塞”(因为它为另一个容器公开了一个卷,但有时我们需要这样做还有其他原因)。
我当时认为这可以工作:
exec sleep infinity;
Run Code Online (Sandbox Code Playgroud)
ps aux 然后将“睡眠”作为 PID 1。太好了,我想,然后它将接收我们从容器外部发送的信号。例如:
docker kill -s INT container_name
Run Code Online (Sandbox Code Playgroud)
但这不起作用,容器继续运行(也适用于 SIGTERM)。正常的杀戮确实有效,但我不明白为什么会有区别(这让我很恼火):
docker kill container_name
Run Code Online (Sandbox Code Playgroud)
当它在我的容器中作为 PID 1 运行时,为什么我不能用 SIGINT/SIGTERM 杀死“睡眠”?我相信当它们在容器中作为 PID 1 运行时,我可以使用 SIGINT/SIGTERM 杀死其他东西(如 bash 脚本)。
这有什么用吗? https://www.fpcomplete.com/blog/2016/10/docker-demons-pid1-orphans-zombies-signals
基本上问题是进程号 1。Linux/unix 内核不愿意以常规方式向该进程发出信号,因为它应该是 init。如果 init 进程终止,系统会立即发出恐慌并重新启动。如果您的进程 1 没有信号处理程序,则该信号就会被丢弃。Sleep 没有任何信号的处理程序,但您可以构建一个 bash 脚本。
基本上你需要做的是在你的 dockerfile 中使用 exec 形式,并将你的 sleep 无限分割成一个循环,因为当 shell 执行命令时 bash 陷阱不会被触发。这会向正在运行的进程 1 发送一个信号并捕获它:
Dockerfile:
FROM ubuntu
ADD foo.sh /tmp
RUN ["/tmp/foo.sh"]
Run Code Online (Sandbox Code Playgroud)
foo.sh:
#!/bin/bash
trap "echo signal;exit 0" SIGINT
while :
do
sleep 1
done
Run Code Online (Sandbox Code Playgroud)
这将对 docker Kill --signal=SIGINT 做出反应。
| 归档时间: |
|
| 查看次数: |
2242 次 |
| 最近记录: |