Docker 从阿尔卑斯山图像中提取SIGTERM

Docker 从阿尔卑斯山图像中提取SIGTERM,docker,dockerfile,gitlab-ci-runner,alpine,sigkill,Docker,Dockerfile,Gitlab Ci Runner,Alpine,Sigkill,我试图从docker实例捕获SIGTERM信号(基本上是在调用docker stop时),但找不到方法,因为每次尝试都有不同的结果 以下是我的设置 Dockerfile FROM gitlab/gitlab-runner:alpine COPY ./start.sh /start.sh ENTRYPOINT ["/start.sh"] start.sh #/bin/bash 撤销注册{ echo“即使什么都没发生,也会有事情发生” 出口 } 陷阱注销器 虽然真实;做 睡眠10 完成 现在

我试图从docker实例捕获SIGTERM信号(基本上是在调用docker stop时),但找不到方法,因为每次尝试都有不同的结果

以下是我的设置

Dockerfile

FROM gitlab/gitlab-runner:alpine

COPY ./start.sh /start.sh

ENTRYPOINT ["/start.sh"]
start.sh

#/bin/bash
撤销注册{
echo“即使什么都没发生,也会有事情发生”
出口
}
陷阱注销器
虽然真实;做
睡眠10
完成
现在我构建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
管理码头工人

$docker运行-it dockertrapcatch
现在,当我运行
docker-stop
docker-kill--signal=SIGTERM
时,我的注销runner函数不会被调用

之后,我更改了start.sh脚本,如下所示(SIGKILL==>EXIT)

#/bin/bash
撤销注册{
echo“即使什么都没发生,也会有事情发生”
出口
}
陷阱注销器退出
虽然真实;做
睡眠10
完成
在此更改后,创建docker映像并运行它
docker stop
仍然不起作用,但
docker kill--signal=SIGTERM
起作用

$docker运行-it dockertrapcatch
即使什么都没发生,也会发生一些事情
$docker kill--signal=SIGTERM 6b667af4ac6c
6b667af4ac6c

我读到docker stop实际上发送了一个SIGTERM,但我认为这次它不起作用了?有什么想法吗?

我可以重现您提出的问题,但当我用
debian:10
替换基本图像时,它不会显示出来

碰巧问题不是由于
alpine
,而是由于
gitlab/gitlab runner:alpine
图像本身,即包含以下行:

trap deregister_runner SIGINT SIGQUIT SIGTERM
停止信号SIGQUIT

更准确地说,上面的行表示
docker stop
将向正在运行的容器发送
SIGQUIT
信号(并在终止容器之前等待“优雅终止时间”,就好像最后发出了
docker kill

如果未使用此Dockerfile指令

请注意,
SIGKILL
对于
STOPSIGNAL
来说是一个非常糟糕的选择,因为KILL信号无法捕获

因此,如果您使用以下行,您的第一个示例应该有效:

trap deregister_runner SIGINT SIGQUIT SIGTERM
这样,只要您发出
docker stop
,或使用
Ctrl-C
键绑定(由于
SIGINT
),就会触发清除功能
deregister\u runner

最后,与
Docker
bash
和signals问题相关的另外两个注释:

  • “优雅终止时间”(在停止和终止之间)可以定制,并且在使用Bash入口点(关于“信号传播”)时存在一些缺陷。我在这个答案中更详细地解释了这两个问题:

  • 请注意,在许多
    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.
    
    (幸运的是,
    gitlab/gitlab-runner:alpine
    的情况并非如此,它确实包含
    bash
    包:)


我相信这可能对你的问题有用。这是否回答了你的问题?实际上,您使用的基本图像在w.r.t.上的表现似乎与我提到的线程有所不同……我将尝试在更完整的答案中重述这一点。