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

因此,例如,如果我尝试以下操作:



docker run -i -t foo /bin/bash

docker attach foo(对于已经运行的容器)

两者都可以将我带到容器中的终端,我如何不停止而退出容器的终端

exitCTR+C都停止容器。

评论

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

您可能如何与Docker的流程进行连接和分离的可能重复项?

#1 楼

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


Ctrl + C(或Ctrl + \)应该可以将您从容器中分离出来但是它会杀死容器,因为您的主要过程是bash。

关于docker的一些教训。
容器不是真正的功能齐全的OS。运行容器时,启动的过程将使用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


(默认情况下将被分离)

评论


为baseimage-docker +1。很高兴知道有一个模板,其中包含有关Docker困难部分的建议。

–mtmacdonald
2014年8月12日15:59

请注意ssh并非绝对必要:blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker

– Adrian Mouat
14年8月18日在12:55

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

–拉维
16年8月15日在6:22



使用Ctrl-p,Ctrl-q分离。这个答案的建议将杀死一个容器。

– Taranaki
17年4月5日在18:05

这对我有用(从下面的答案中获取):以-ti -d开头,然后以docker attach附加,然后先按ctrl + p再按ctrl + q分离。我以为,我可以只使用一种键盘快捷键。

– CGFoX
18/09/27在13:37

#2 楼

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


评论


似乎不适用于(尝试退出附加的Wekan容器)。

–danger89
16年6月11日在21:49

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

–汤姆·古达(Thamme Gowda)
16年7月19日在18:03

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

– Riscie
16-10-31在8:45



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

– Mohyaddin Alaoddin
19年3月8日在11:10

#3 楼

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


已分配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 (没有-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]$    


拆卸的第三种方法

有一种拆卸方法而不会杀死虽然容器您需要另一个外壳。总之,在另一个脱壳的外壳中运行它,并使容器继续运行。

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


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

评论


第三种方式对我有效。谢谢。如果要附加到多个实例,并且只想从一个实例分离。可以杀死特定进程:ps -ef | grep attach->获取pid。然后:杀死-9

–phanhuy152
18-4-4在9:44



在docker Attach之后,pkill是唯一对我有用的东西

–sm4rk0
19年2月7日在16:11

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

–安吉洛
19-10-11在21:43

其他信号就是那个信号。他们告诉过程什么类型的信号,并给它一个行动和做某事的机会。 Kill -9信号没有。该过程已终止,无法追索。我的猜测是其他信号使容器有机会关闭,而-9则没有。

– Berto
19-10-12在11:26

这超级有帮助。谢谢!

–埃文·扎米尔(Evan Zamir)
19-10-21在23:06

#4 楼

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

评论


最好使用Ctrl + P和Ctrl + Q

–sib10
16年6月17日在11:58

Ctrl + P,Q(仍然按住Ctrl);)

–双足
17年4月19日在17:19

它返回我:来自守护程序的错误响应:容器f560a0ad6806150b2775d0b6e6d5f7065a03775bae858fb4fb7df05a277976db未运行

– Webwoman
19年3月1日在13:27



#5 楼

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


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

docker run -dti foo bash


然后您可以进入容器并使用
运行bash
docker exec -ti ID_of_foo bash


无需安装sshd :)

评论


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

– Nehal J Wani
16年2月26日在16:57

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

–thiagowfx
17年7月3日,19:11



这是适用于我的特定情况的唯一命令。使用VS Code在Docker中运行测试服。在我的情况下,这是一个Rails应用程序,因此要启动后台容器docker-compose run -d --name app_tests应用程序Spring服务器,然后我可以通过将vscode test命令设置为docker exec -ti app_tests spring rspec来运行测试。

–摇摆
20 Dec 6'19:12



#6 楼

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

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


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

评论


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

– Taranaki
17年2月14日在7:26

这应该是可接受的答案,包括@taranaki的注释,Ctrl + P,Q对php:7.3-apache不起作用

– MKaama
19年5月23日在19:04



#7 楼

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

#8 楼

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

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

#9 楼

您可以在运行--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默认序列与您用于其他应用程序的密钥序列冲突,这将很有用。有两种方法来定义自己的分离键序列,作为每个容器的覆盖或整个配置的配置属性。

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


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

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

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

#10 楼

您只需发送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
虽然有点hack,但是行得通!

#11 楼

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

评论


除非您在生产系统上

–mvreijn
20-10-20在11:47