简体   繁体   English

如何使用 CTRL+C 退出并终止正在运行的 Docker 容器?

[英]How to Exit and Kill the Running Docker Container with CTRL+C?

TL; TL; DR: how should I write a Dockerfile or docker commands to run docker containers so that I can stop and exit the running docker container when I hit ctrl+c ? DR:我应该如何编写DockerfileDockerfile命令来运行Dockerfile容器,以便在按下ctrl+c时可以停止并退出正在运行的 docker 容器?


Background背景

I need to run an infinite while loop in shell script.我需要在 shell 脚本中运行无限 while 循环。 When I ran this script locally, the ctrl+c command will exit the infinite loop.当我在本地运行这个脚本时, ctrl+c命令会退出无限循环。

# content of sync.sh

while true; do
  echo "Do something!"
  some_syncing_command || {
    rm -rf /tmp/healthy && break
  }
  echo "Finish doing something!"
  touch /tmp/healthy
  sleep ${waitingSeconds}
done

So based on the shell script, I then created a Docker Image with the following Dockerfile content:因此,基于 shell 脚本,我创建了一个包含以下Dockerfile内容的 Docker 镜像:

FROM debian:stretch 
COPY sync.sh .

ENTRYPOINT ["/sync.sh"]

and build the image by running docker build -t infinite-loop .并通过运行docker build -t infinite-loop .构建映像docker build -t infinite-loop .

Problem问题

However, after trying different attempts to run the infinite-loop image, I cannot stop and exit the running docker container after hitting ctrl + c .但是,在尝试不同的尝试运行infinite-loop图像后,我无法在按ctrl + c后停止并退出正在运行的 docker 容器。 Here are the docker commands I used to run the docker image:以下是我用来运行 docker 镜像的 docker 命令:

  1. docker run --rm to-infinity-1 infinite-loop
  2. docker run --rm -it to-infinity-2 infinite-loop
  3. docker run --rm -d to-infinity-3 infinite-loop , then run docker attach on to-infinity-3 docker run --rm -d to-infinity-3 infinite-loop ,然后在to-infinity-3docker run --rm -d to-infinity-3 infinite-loop docker attach

All of the above commands fail to stop and exit the infinite loop after executing ctrl+c directly.以上所有命令直接执行ctrl+c后都无法停止并退出死循环。 Hence I need to run docker stop [container-name] to stop the running containers of infinite loops.因此我需要运行docker stop [container-name]来停止无限循环的运行容器。 What should I change in my implementation to resolve this problem?我应该在我的实现中改变什么来解决这个问题?

Thank you.谢谢你。

Edit: additional context, I am using kubernetes with the infinite loop container.编辑:附加上下文,我将 kubernetes 与无限循环容器一起使用。 I wonder if this ctrl+c problem (related to SIGINT) will interfere with kubernetes if I want to gracefully stop and exit the running pod.我想知道如果我想优雅地停止并退出正在运行的 pod,这个ctrl+c问题(与 SIGINT 相关)是否会干扰 kubernetes。 Note that although the ctrl+c is problematic, I was still able to use docker stop to stop the running containers.请注意,虽然ctrl+c有问题,但我仍然能够使用docker stop来停止正在运行的容器。

“docker run” traps or ignores ctrl+c. “ docker run”陷阱或忽略ctrl + c。

If you don't want to lose your shell you can trying stopping the container from another terminal on the same docker host. 如果您不想丢失外壳,可以尝试从同一docker主机上的另一个终端停止容器。

Open a new shell and execute 打开一个新的shell并执行

$ docker ps # get the id of the running container
$ docker stop <container> # kill it (gracefully)

The container process will end and your original shell will be released. 容器过程将结束,原始外壳将被释放。

I think you'll need to use trap, here's an example of my code: 我认为您需要使用陷阱,这是我的代码示例:

done=0
trap 'done=1' TERM INT

while [ $done = 0 ]; do
  #doingstuff
  sleep $someinterval &
  wait
done

ctrl + c is a signal so you'll need a signal handler. ctrl + c是一个信号,因此您需要一个信号处理程序。 Moreover sleep will need to be run in background so that your trap won't be held until sleep is completed. 此外,睡眠将需要在后台运行,这样才能在睡眠完成之前保持陷阱。

[1] Trap: https://www.shellscript.sh/trap.html [1]陷阱: https//www.shellscript.sh/trap.html

I know this answer is late but for the searchers:我知道这个答案来晚了,但对于搜索者来说:

The trick is to use tty and to detach but then also reattach.诀窍是使用 tty 并分离然后重新附加。 I. e., attach to the run command that runs with -d and -t .即,附加到使用-d-t运行的运行命令。

  docker attach $(docker run -d --rm --network host \
         -t \
         --user $(id -u):$(id -g) \
         -v "/home:/home" \
         -v "/etc/passwd:/etc/passwd:ro" \
         -v "/etc/group:/etc/group:ro" \
         -w $PWD node:latest npx eleventy --serve)

This shows the output from the terminal for as long as it runs, but also responds to Ctrl+c.只要终端运行,它就会显示终端的输出,但也会响应 Ctrl+c。

credit to Les Hazelwood归功于 Les Hazelwood

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM