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


313

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

因此,例如,如果我尝试:

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

两者都将我带到集装箱中的码头,如何在不停止的情况下退出集装箱的码头?

exit并且CTR+C都停止了容器。


“容器”只是进程可以在其中运行的一组受限名称空间(进程名称空间,文件系统名称空间等)。如果名称空间中没有进程,那么该名称空间是否真的存在?这不像是一个虚拟机,那里有一个内核在回答时钟中断&c。而不管。
Charles Duffy 2014年

Answers:


166

更新:如下面的答案中所述,Ctrl+ pCtrl+ q现在将交互方式转换为守护程序方式。


那么Ctrl+ C(或Ctrl+ \)应分开你从容器中,但它会杀死容器,因为你的主要过程是一个bash。

关于Docker的一些课程。容器不是真正的全功能操作系统。运行容器时,启动的过程将使用PID 1并假定具有初始化电源。因此,当该进程终止时,守护进程将停止容器,直到启动一个新进程(通过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
为baseimage-docker +1。很高兴知道有一个模板,其中包含有关Docker困难部分的建议。
mtmacdonald 2014年


1
在-d模式下运行包含对象非常有帮助。另外,通过Dockerfile启动ssh的链接使我的生活变得轻松。
拉维

56
分离使用CTRL-P,CTRL-Q。这个答案的建议将杀死一个容器。
taranaki

4
这个工作对我来说(从下面回答):开始-ti -d,然后用连接docker attach,然后用分离第一 Ctrl + P键,然后按Ctrl + Q。我以为,我只能使用一种键盘快捷键。
CGFoX

526

键入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")

4
似乎不适用于(尝试退出附加的Wekan容器)。
危险89年

7
我之所以访问此页面,是因为我记不清此组合键!:-D
Thamme Gowda

10
@ danger89 ctrl-p,ctrl-q仅在以交互方式(-it)启动容器时才起作用。如果已将其以守护进程模式(-d)启动并附加到它,则只需退出它,它仍将在后台运行。
Riscie '16

1
@SlimShady然后按Ctrl + P,然后按Ctrl + Q退出,不是其中一个而是按此顺序退出。
Mohyaddin Alaoddin

160

我对此进行了深入研究,以上所有答案部分都是正确的。这完全取决于容器的启动方式。容器启动时归结为以下内容:

  • 是分配的TTY(-t
  • 标准输入未打开(-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不带 -i)用于启动容器时才有效:

[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]$    

分离的第三种方式

有一种方法可以在不杀死容器的情况下进行分离;您需要另一个外壳。总而言之,在另一个脱壳的外壳中运行它,并使容器继续运行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
第三种方式对我有效。谢谢。如果要附加到多个实例,而只想从一个实例分离。可以杀死特定进程:ps -ef | grep attach->获取pid。然后:杀死-9 <pid>
phanhuy152 '18

在码头工人附加之后,pkill是唯一对我
有用的

为什么我们需要-9。我注意到如果我们不使用-9,它将关闭容器。
安杰洛

其他信号就是那个信号。他们告诉过程什么类型的信号,并给它机会采取行动和采取行动。该kill -9信号不。该过程已终止,无法追索。我的猜测是其他信号使容器有机会关闭,而-9实际上没有。
berto

1
这超级有帮助。谢谢!
埃文·扎米尔

40

如果您执行“ docker attach“ container id”,则进入容器。要在不停止容器的情况下退出容器,则需要输入Ctrl+ P+Q


6
最好使用Ctrl + P和Ctrl + Q
sib10

4
Ctrl + P,Q(仍然保持Ctrl);)
dimpiax

它返回我:Error response from daemon: Container f560a0ad6806150b2775d0b6e6d5f7065a03775bae858fb4fb7df05a277976db is not running
Webwoman

30

我认为Ashwin的答案是最正确的,下面是我的旧答案。


我想在这里添加另一个选项,如下所示运行容器

docker run -dti foo bash

然后,您可以进入容器并使用以下命令运行bash

docker exec -ti ID_of_foo bash

无需安装sshd :)


我认为在第二个命令中,您需要将foo替换为foo的容器ID
Nehal J Wani

在这种情况下,我认为docker attach通过重新附加到第一个bash运行会更加标准。docker exec在这里也可以使用,但是除了第一个过程外,它还创建了一个新的bash过程。当然,该过程是在与第一个相同的上下文/环境/容器中创建的,但是过程是不同的(类比是在您喜欢的终端仿真器中打开一个新的终端选项卡)。
thiagowfx

20

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


16

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

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

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


6
尽管--sig-proxy = false非常有用,但对于未指定容器的已附加容器不起作用。问题是,附加后似乎没有办法在不终止进程的情况下进行分离,包括“终止docker attach进程”。Cp,Cq不适用于附加容器,只能用于交互式容器(如问题所使用的容器)。
taranaki

1
这应该是公认的答案,包括@taranaki的注释,Ctrl + P,Q不适用于php:7.3-apache
MKaama

10

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

-f标志使之可以followed实时更新容器的输出。对于调试或监视非常有用。


8

您可以--detach-keys在运行时使用该选项docker attach以覆盖默认的CTRL+ PCTRL+ 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默认序列与您用于其他应用程序的密钥序列冲突,这将很有用。定义您自己的分离键序列的方法有两种,一种是按容器覆盖,另一种是整个配置中的配置属性。

要覆盖单个容器的序列,请将该--detach-keys="<sequence>"标志与docker attach命令一起使用。的格式为<sequence>letter [a-Z]ctrl-以下任意一项的组合:

  • az(单个小写字母字符)
  • @(符号处)
  • [(左括号)
  • \(两个反斜杠)
  • _(下划线)
  • ^(插入符号)

这些actrl-aX,或ctrl-\\的值是有效的密钥序列的所有实施例。要为所有容器配置不同的配置默认键序列,请参阅“ 配置文件”部分。

注意:此功能自docker版本1.10+起有效(在回答此问题时,当前版本为18.03)


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.