[英]Catching SIGTERM from alpine image
I was trying to catch SIGTERM signal from a docker instance (basically when docker stop is called) but couldn't find a way since I have different results for each try I performed.我试图从 docker 实例中捕获 SIGTERM 信号(基本上是在调用 docker stop 时)但找不到方法,因为我执行的每次尝试都有不同的结果。
Following is the setup I have以下是我的设置
Dockerfile文件
FROM gitlab/gitlab-runner:alpine
COPY ./start.sh /start.sh
ENTRYPOINT ["/start.sh"]
start.sh启动文件
#!/bin/bash
deregister_runner() {
echo "even if nothing happened, something happened"
exit
}
trap deregister_runner SIGTERM
while true; do
sleep 10
done
Now I build the docker image现在我构建了 docker 镜像
$ docker build -t dockertrapcatch .
Sending build context to Docker daemon 51.71kB
Step 1/3 : FROM gitlab/gitlab-runner:alpine
---> 9f8c39873bee
Step 2/3 : COPY ./start.sh /start.sh
---> Using cache
---> ebb3cac0c509
Step 3/3 : ENTRYPOINT ["/start.sh"]
---> Using cache
---> 7ab67fe5a714
Successfully built 7ab67fe5a714
Successfully tagged dockertrapcatch:latest
Run the docker运行泊坞窗
$ docker run -it dockertrapcatch
Now when I run docker stop <<container_id_here>>
or docker kill --signal=SIGTERM <<container_id_here>>
, my deregister_runner function is not called.现在,当我运行
docker kill --signal=SIGTERM <<container_id_here>>
docker stop <<container_id_here>>
或docker kill --signal=SIGTERM <<container_id_here>>
,不会调用我的deregister_runner函数。
After that I changed the start.sh script as following (SIGKILL ==> EXIT)之后,我将start.sh脚本更改为如下(SIGKILL ==> EXIT)
#!/bin/bash
deregister_runner() {
echo "even if nothing happened, something happened"
exit
}
trap deregister_runner EXIT
while true; do
sleep 10
done
After this change and creating the docker image and running it docker stop <<container_id_here>>
still does not work but docker kill --signal=SIGTERM <<container_id_here>>
works!在此更改并创建 docker 映像并运行它之后,
docker stop <<container_id_here>>
仍然无效,但docker kill --signal=SIGTERM <<container_id_here>>
有效!
$ docker run -it dockertrapcatch
even if nothing happened, something happened
$ docker kill --signal=SIGTERM 6b667af4ac6c
6b667af4ac6c
I read that actually docker stop
sends a SIGTERM but I think this time it is not working?我读到实际上
docker stop
发送了一个SIGTERM但我认为这次它不起作用? Any idea?任何的想法?
I can reproduce the issue you raise, while it does not show up when I replace the base image with debian:10
, for example.我可以重现您提出的问题,例如,当我用
debian:10
替换基本映像时它不会出现。
It happens the issue is not due to alpine
but to the gitlab/gitlab-runner:alpine
image itself, namely this Dockerfile
contains the following line:碰巧这个问题不是由
alpine
引起的,而是由gitlab/gitlab-runner:alpine
图像本身引起的,即这个Dockerfile
包含以下行:
STOPSIGNAL SIGQUIT
To be more precise, the line above means docker stop
will send a SIGQUIT
signal to the running containers (and wait for a "graceful termination time" before killing the containers, as if a docker kill
were issued in the end).更准确地说,上面的行意味着
docker stop
将向正在运行的容器发送一个SIGQUIT
信号(并在杀死容器之前等待“正常终止时间”,就好像最后发出了docker kill
一样)。
If this Dockerfile directive is not used, the default signal sent by docker stop
is SIGTERM .如果未使用此 Dockerfile 指令,则 docker
docker stop
发送的默认信号为 SIGTERM 。
Beware that SIGKILL
would be a very poor choice for STOPSIGNAL
, given that the KILL signal cannot be trapped.请注意,
SIGKILL
将是STOPSIGNAL
一个非常糟糕的选择,因为无法捕获 KILL 信号。
So, your first example should work if you use the following line:因此,如果您使用以下行,您的第一个示例应该可以工作:
trap deregister_runner SIGINT SIGQUIT SIGTERM
This way, your cleanup function deregister_runner
will be triggered anytime you issue a docker stop
, or use the Ctrl-C
keybinding (thanks to SIGINT
).这样,您的清理函数
deregister_runner
将在您发出docker stop
或使用Ctrl-C
键绑定(感谢SIGINT
)时触发。
Finally, two additional notes related to this question of Docker
, bash
and signals:最后,关于
Docker
、 bash
和信号的这个问题的两个附加说明:
The "graceful termination time" (between stop and kill) can be customized, and there are some pitfalls when using a Bash entrypoint (regarding the "signal propagation"). “正常终止时间”(停止和终止之间)可以自定义,并且在使用 Bash 入口点(关于“信号传播”)时存在一些陷阱。 I explained both issues in more detail in this SO answer: Speed up docker-compose shutdown .
我在这个 SO 答案中更详细地解释了这两个问题:加速 docker-compose shutdown 。
Beware that in many alpine
images, bash
is not pre-installed, eg:请注意,在许多
alpine
映像中,没有预装bash
,例如:
$ sudo docker run --rm -it alpine /bin/bash /usr/bin/docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \\"/bin/bash\\": stat /bin/bash: no such file or directory": unknown.
(fortunately, this was not the case of gitlab/gitlab-runner:alpine
, which indeed contains the bash
package :) (幸运的是,这不是
gitlab/gitlab-runner:alpine
,它确实包含bash
包:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.