【问题标题】:Why can't I always kill a docker process with Ctrl-C?为什么我不能总是用 Ctrl-C 杀死一个 docker 进程?
【发布时间】:2023-04-08 06:29:01
【问题描述】:

我有一个脚本,我想有选择地在容器中运行它。我观察到,如果我运行一个中间脚本,它可以被 Ctrl-C 杀死,但是如果我不这样做,它就不能。
这是一个例子:
test1.sh:

#!/bin/bash

if [ "${1}" = true ]; then
  while true; do echo "args: $@"; sleep 1; done
else
  docker run --rm -it $(docker build -f basic-Dockerfile -q .) /test2.sh $@
fi

test2.sh:

#!/bin/bash

/test1.sh true $@

basic-Dockerfile:

FROM alpine:3.7

RUN apk add --no-cache bash
COPY test1.sh test2.sh /
ENTRYPOINT ["bash"]

运行./test1.sh true foo bar 将愉快地打印出true foo bar,运行./test1.sh foo bar 将在容器中执行相同的操作。发送Ctrl-C 将终止进程并按预期删除容器。
但是,如果我尝试通过将 /test2.sh $@ 更改为 /test1.sh true $@ 来消除对额外文件的需求:
test1.sh

#!/bin/bash

if [ "${1}" = true ]; then
  while true; do echo "args: $@"; sleep 1; done
else
  docker run --rm -it $(docker build -f basic-Dockerfile -q .) /test1.sh true $@
fi

那么进程不能再用Ctrl-C 终止,而是必须用docker kill 停止。

为什么会这样?

Docker 版本 18.06.1-ce 在 WSL 中的 Windows 10 上运行

【问题讨论】:

    标签: docker


    【解决方案1】:

    这是 docker 中常见的误解,但这是有充分理由的。

    当一个进程在 Linux 中以 PID 1 运行时,它的行为会有所不同。具体来说,它会忽略信号作为 SIGTERM(您在按下 Ctrl-C 时发送),除非脚本被编码为这样做。当 PID > 1 时不会发生这种情况。

    这就是为什么您的第二个场景有效(PID 1 是 script2.sh,它委托 script1.sh 中的信号,因为它不是 PID1 而停止)但不是第一个(script1.sh 是 PID 1,因此它不会以 SIGTERM 结束)。

    要解决这个问题,您可以在 script1.sh 中捕获信号并退出:

    exit_func() {
            echo "SIGTERM detected"            
            exit 1
    }
    trap exit_func SIGTERM SIGINT
    

    或者告诉docker run 用另一个进程作为 PID 1 来初始化容器。具体来说,如果你将--init 添加到 docker run 并且没有更多参数,它会使用一个默认程序 tini,准备处理这些情况:

    docker run --rm -it --init $(docker build -f basic-Dockerfile -q .) /test1.sh true $@
    

    【讨论】:

      【解决方案2】:

      您也可以使用exec 将当前shell 替换为新的shell,可以使用ctrl-c 停止 例如 start.sh 脚本,它启动 nginx 服务器并运行 uwsgi

      #!/usr/bin/env bash
      
      service nginx start
      uwsgi --ini uwsgi.ini
      

      应该改为

      #!/usr/bin/env bash
      
      service nginx start
      exec uwsgi --ini uwsgi.ini
      

      这些更改后,按 ctrl c 将停止容器

      【讨论】:

        猜你喜欢
        • 2020-01-10
        • 2019-11-13
        • 1970-01-01
        • 2014-12-17
        • 2021-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多