abd*_*hin 5 sigkill docker dockerfile gitlab-ci-runner alpine-linux
我试图从 docker 实例捕获 SIGTERM 信号(基本上是在调用 docker stop 时),但找不到方法,因为我执行的每次尝试都有不同的结果。
以下是我的设置
Dockerfile
FROM gitlab/gitlab-runner:alpine
COPY ./start.sh /start.sh
ENTRYPOINT ["/start.sh"]
Run Code Online (Sandbox Code Playgroud)
启动文件
FROM gitlab/gitlab-runner:alpine
COPY ./start.sh /start.sh
ENTRYPOINT ["/start.sh"]
Run Code Online (Sandbox Code Playgroud)
现在我构建 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 Code Online (Sandbox Code Playgroud)
运行泊坞窗
#!/bin/bash
deregister_runner() {
echo "even if nothing happened, something happened"
exit
}
trap deregister_runner SIGTERM
while true; do
sleep 10
done
Run Code Online (Sandbox Code Playgroud)
现在,当我运行docker stop <<container_id_here>>
or时docker kill --signal=SIGTERM <<container_id_here>>
,我的deregister_runner函数不会被调用。
之后我更改了start.sh脚本如下(SIGKILL ==> EXIT)
$ 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 Code Online (Sandbox Code Playgroud)
进行此更改并创建 docker 映像并运行它后docker stop <<container_id_here>>
仍然不起作用,但docker kill --signal=SIGTERM <<container_id_here>>
可以工作!
$ docker run -it dockertrapcatch
Run Code Online (Sandbox Code Playgroud)
#!/bin/bash
deregister_runner() {
echo "even if nothing happened, something happened"
exit
}
trap deregister_runner EXIT
while true; do
sleep 10
done
Run Code Online (Sandbox Code Playgroud)
我读到实际上docker stop
发送了一个SIGTERM但我认为这次它不起作用?任何想法?
我可以重现您提出的问题,但当我用 替换基本图像时debian:10
,它不会显示。
问题不是alpine
由图像本身引起的,而是由图像本身引起的gitlab/gitlab-runner:alpine
,即包含以下行:Dockerfile
STOPSIGNAL SIGQUIT
更准确地说,上面的行意味着docker stop
将向正在运行的容器发送一个SIGQUIT
信号(并在杀死容器之前等待“优雅终止时间”,就像docker kill
最后发出了 a 一样)。
如果不使用此 Dockerfile 指令,则发送的默认信号docker stop
是 SIGTERM。
请注意,鉴于无法捕获 KILL 信号,这SIGKILL
对于 来说是一个非常糟糕的选择。STOPSIGNAL
因此,如果您使用以下行,您的第一个示例应该可以工作:
trap deregister_runner SIGINT SIGQUIT SIGTERM
Run Code Online (Sandbox Code Playgroud)
这样,deregister_runner
只要您发出docker stop
或使用Ctrl-C
键绑定(感谢SIGINT
),您的清理功能就会被触发。
Docker
最后,与 、和 信号问题相关的两个附加注释bash
:
“优雅终止时间”(停止和终止之间)可以自定义,并且使用 Bash 入口点时存在一些陷阱(关于“信号传播”)。我在这个答案中更详细地解释了这两个问题:加速 docker-compose shutdown。
请注意,在许多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.
Run Code Online (Sandbox Code Playgroud)
(幸运的是,情况并非如此gitlab/gitlab-runner:alpine
,它确实包含该bash
包:)
归档时间: |
|
查看次数: |
6241 次 |
最近记录: |