正确的方法从容器中分离而不停止它

时间:2014-08-12 14:48:01

标签: docker

在Docker 1.1.2(最新版)中,在不停止容器的情况下从容器中分离出来的正确方法是什么?

例如,如果我尝试:

  • docker run -i -t foo /bin/bash
  • docker attach foo(已经在运行的容器)

这两个都让我到了集装箱的终端,如何在不停止的情况下退出集装箱的终端?

exitCTR+C都会停止容器。

12 个答案:

答案 0 :(得分:458)

键入 Ctrl + p Ctrl + q 将帮助您将交互模式转换为守护进程模式。

请参阅https://docs.docker.com/v1.7/articles/basics/#running-an-interactive-shell

# To detach the tty without exiting the shell,
# use the escape sequence Ctrl-p + Ctrl-q
# note: This will continue to exist in a stopped state once exited (see "docker ps -a")

答案 1 :(得分:114)

我挖掘了这个,上面的所有答案都是正确的。这一切都取决于容器的启动方式。当容器启动时,它归结为以下内容:

  • 是分配的TTY(-t
  • 是stdin左开(-i

^P^Q 可以正常工作但是:您需要在启动容器时指定-t-i

[berto@g6]$ docker run -ti -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
b26e39632351192a9a1a00ea0c2f3e10729b6d3e22f8e0676d6519e15c08b518

[berto@g6]$ docker attach test
# here I typed ^P^Q
read escape sequence

# i'm back to my prompt
[berto@g6]$ docker kill test; docker rm -v test
test
test

ctrl+c 确实有效但是:启动容器时,只需指定 -t

[berto@g6]$ docker run -t -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
018a228c96d6bf2e73cccaefcf656b02753905b9a859f32e60bdf343bcbe834d

[berto@g6]$ docker attach test
^C

[berto@g6]$    

分离的第三种方式

有一种方法可以在不杀死容器的情况下分离;你需要另一个shell。总之,在另一个shell中运行此分离并使容器运行pkill -9 -f 'docker.*attach'

[berto@g6]$ docker run -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
b26e39632351192a9a1a00ea0c2f3e10729b6d3e22f8e0676d6519e15c08b518

[berto@g6]$ docker attach test
# here I typed ^P^Q and doesn't work
^P
# ctrl+c doesn't work either
^C
# can't background either
^Z

# go to another shell and run the `pkill` command above

# i'm back to my prompt
[berto@g6]$

为什么呢?因为您正在杀死将您连接到容器的进程,而不是容器本身。

答案 2 :(得分:103)

更新:如下所述 Ctrl + p Ctrl + q 现在将交互模式转换为守护进程模式。


Ctrl + C (或 Ctrl + \ )应该从容器中分离出来但它会杀死容器,因为你的主进程是一个bash。

关于码头工人的一点教训。 容器不是真正的全功能操作系统。当您运行容器时,您启动的进程将获取PID 1并假定为init power。因此,当该进程终止时,守护进程会停止容器,直到启动新进程(通过docker start)(有关此问题的更多解释http://phusion.github.io/baseimage-docker/#intro

如果您想要一个始终以分离模式运行的容器,我建议您使用

docker run -d foo

在容器上使用ssh服务器。 (最简单的方法是遵循dockerizing openssh教程https://docs.docker.com/engine/examples/running_ssh_service/

或者您可以通过

重新启动容器
docker start foo

(默认情况下会分离)

答案 3 :(得分:34)

如果您执行了#34; docker attach" container id"你进入容器。 要在不停止容器的情况下退出容器,您需要输入" Ctrl + P + Q"

答案 4 :(得分:26)

我认为Ashwin的回答是最正确的,我的回答如下。

<小时/> 我想在这里添加另一个选项,即运行容器,如下所示

docker run -dti foo bash

然后,您可以输入容器并使用

运行bash
docker exec -ti ID_of_foo bash

无需安装sshd:)

答案 5 :(得分:19)

从交互式容器中分离的默认方式是 Ctrl + P Ctrl + Q ,但是你可以在运行新容器或使用the --detach-keys flag附加到现有容器时覆盖它。

答案 6 :(得分:13)

如果您通过docker attach附加,则可以通过终止Docker附加进程来分离。 更好的方法是使用sig-proxy参数来避免将Ctrl + C传递给容器:

docker attach --sig-proxy=false [container-name]

docker run命令可以使用相同的选项。

答案 7 :(得分:6)

运行--detach-keys时,您可以使用docker attach选项来覆盖默认的CTRL+P, CTRL + Q序列(并不总是有效)。

例如,当您运行docker attach --detach-keys="ctrl-a" test并按CTRL+A时,您将退出容器,而不会将其删除。

其他例子:

  • docker attach --detach-keys="ctrl-a,x" test - 按CTRL+A,然后按X退出
  • docker attach --detach-keys="a,b,c" test - 按A,然后按B,然后按C退出

摘自官方文档:

如果需要,可以配置覆盖Docker键序列以进行分离。如果Docker默认序列与您用于其他应用程序的键序列冲突,这将非常有用。有两种方法可以定义您自己的分离键序列,作为每个容器覆盖或整个配置的配置属性。

要覆盖单个容器的序列,请使用带有docker attach命令的--detach-keys="<sequence>"标志。 <sequence>的格式为字母[a-Z],或ctrl-与以下任何内容相结合:

  • a-z(单个小写字母字符)
  • @(at sign)
  • [(左括号)
  • \(两个反向斜线)
  • _(下划线)
  • ^(插入符号)

这些actrl-aXctrl-\\值都是有效密钥序列的示例。要为所有容器配置不同的配置默认密钥序列,请参阅Configuration文件部分。

注意:这是因为docker版本1.10+(在此回答时,当前版本为18.03)

答案 8 :(得分:6)

如果您只想查看从容器中运行的进程的输出,您可以执行简单的docker container logs -f <container id>

-f标志使得容器的输出为followed并实时更新。对调试或监控非常有用。

答案 9 :(得分:3)

在 Docker 容器中至少必须运行一个进程,那么只有容器会在后台不退出

例如在 ubuntu docker image 中,

要创建具有分离模式的新容器(至少在进程上运行后台),

docker run -d -i -t f63181f19b2f /bin/bash

它将为此图像(ubuntu)id f63181f19b2f 创建一个新的包含。容器将在分离模式下运行(在后台运行),届时一个小进程 tty bash shell 将在后台运行。因此,容器将继续运行,直到 bash shell 进程被杀死。

要附加到正在运行的后台容器,请使用

docker attach  b1a0873a8647

如果你想在不退出的情况下从容器中分离(不杀死 bash shell), 默认情况下,您可以使用 ctrl-p,q。它会在不退出容器的情况下从容器中出来(运行后台。这意味着不会杀死 bash shell)。

您可以在附加期间将自定义命令传递给容器,

docker attach --detach-keys="ctrl-s" b1a0873a8647

这次 ctrl-p,q 转义序列不起作用。相反,ctrl-s 将用于退出容器。您可以传递任何键,例如 (ctrl-*)

答案 10 :(得分:1)

您可以通过发送 SEGKILL 来简单地终止 docker cli 进程。如果你用

启动容器

docker run -it some/container

你可以得到它的pid

ps -aux | grep docker

user   1234  0.3  0.6 1357948 54684 pts/2   Sl+  15:09   0:00 docker run -it some/container

假设它是 1234,你可以“分离”它

kill -9 1234

这有点像黑客,但它有效!

答案 11 :(得分:-2)

旧帖子,但退出后再重新启动...问题是,如果您在Windows计算机上,则Ctrl p或Ctrl P与打印绑定...退出启动容器不会对任何事情造成伤害