您如何与Docker的流程连接和分离?


456

我可以附加到docker进程,但是Ctrl+ c不能与其分离。exit基本上停止了这个过程。

建议使用什么工作流程来运行流程,偶尔将其附加以进行一些更改,然后分离?


4
使用nsenter时,我只按Ctrl-D即可。
user2105103 2014年

是否关闭xtermkonsole等方面的工作?它对我有用(我变得超脱)。
Vytenis Bivainis

Answers:


666

要在不退出外壳的情况下分离tty,请使用转义序列Ctrl+ P后跟Ctrl+ Q。更多细节在这里

此来源的其他信息:

  • docker run -t -i→可以^P^Q与docker attach 分离并重新连接
  • docker run -i→不能与分离^P^Q; 会破坏标准输入
  • docker run→无法与之分离^P^Q;可以SIGKILL客户端;可以使用docker attach重新附加

46
如果它确实按照文档中所述工作,这将是一个很好的答案。
allingeek

20
我发现即使使用-it运行,如果您还使用清理标志(--rm)启动容器,分离序列也会失败。这对某些人来说可能是显而易见的,但它比我想承认的更经常咬我。
allingeek 2014年

7
另一个选择是只关闭终端窗口或cmd-w :)
buildmaestro

3
您可以设置如配置分离键"detachKeys": "ctrl-a,a"在.docker / config.json文件或 --detach-keys "ctrl-a,a"与附加等在命令行上
马修·汉尼根

4
Ctrl + Z不分离;它只是过程的背景。它与分离不同,并且会降低性能。
Zenexer

177

退房还--sig-proxy选项

docker attach --sig-proxy=false 304f5db405ec

然后使用CTRL+ c分离


4
为了尝试从运行而不是附加开始,我尝试了: docker run -ti --sig-proxy=false busybox top 似乎不起作用,该过程被ctrl-c杀死了,但是从 docker run -t -sig-proxy=false busybox top 似乎开始起作用并启用了ctrl-c退出
Henning 2014年

Ctrl-c也将停止容器。
Evan Hu

这是此处列出的解决方案中唯一适用于运行Docker 19.03.5的Debian 9服务器的解决方案。问题是,为什么这不是附加命令的默认设置?这似乎是最常见的用例。
fviktor '19

Ctrl-p,Ctrl-q序列对我不起作用(从Docker容器附加xyz开始)..但是可以。感谢@czerasz
PravyNandas

92

如果您只想对文件进行一些修改或检查进程,那么这里可能就是您想要的另一种解决方案。

您可以运行以下命令从现有容器中执行新过程:

sudo docker exec -ti [CONTAINER-ID] bash

将使用bash shell启动一个新进程,您可以直接通过Ctrl+ 退出它C,这不会影响原始进程。


6
这项工作有效,您可以在完成操作后键入“退出”,而不会影响原始过程。
Eko3alpha

这是连接到正在运行的容器的好方法。但是,如果(例如)我的容器中正在运行某些进程并且想要重新启动该进程怎么办?嗯,我可以取消旧进程,重新启动新进程,然后使用Cp,Cq,因为它是交互式tty,所以可以使用。我也喜欢--sig-proxy = false方法,但这更通用,不会强制中断当前过程。
taranaki '17

“ attach”在Docker中具有特定含义,exec不是吗。
16:09

48

我认为这应视情况而定,以以下容器为例:

# docker run -it -d ubuntu
91262536f7c9a3060641448120bda7af5ca812b0beb8f3c9fe72811a61db07fc
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
91262536f7c9        ubuntu              "/bin/bash"         5 seconds ago       Up 4 seconds                            serene_goldstine

(1)使用“ docker attach”连接容器:

由于“ docker attach不会分配新的tty,而是重用原始的正在运行的tty,因此,如果您运行exit命令,它将导致正在运行的容器退出:

# docker attach 91262536f7c9
exit
exit
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
91262536f7c9        ubuntu              "/bin/bash"         39 minutes ago      Exited (0) 3 seconds ago                       serene_goldstine

因此,除非您真的想退出正在运行的容器,否则应使用Ctrl+ p+ Ctrl+ q

(2)使用“ docker exec

由于“ docker exec分配一个新的tty,因此我认为您应该使用exit而不是Ctrl+ p+ Ctrl+ q

以下是执行Ctrl+ p+ Ctrl+ q退出容器:

# docker exec -it 91262536f7c9 bash
root@91262536f7c9:/# ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  18160  1908 ?        Ss+  04:03   0:00 /bin/bash
root        15  0.0  0.0  18164  1892 ?        Ss   04:03   0:00 bash
root        28  0.0  0.0  15564  1148 ?        R+   04:03   0:00 ps -aux
root@91262536f7c9:/# echo $$
15

然后再次登录容器,您将看到bash之前docker exec命令中的过程仍然有效(PID为15):

# docker exec -it 91262536f7c9 bash
root@91262536f7c9:/# ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  18160  1908 ?        Ss+  04:03   0:00 /bin/bash
root        15  0.0  0.0  18164  1892 ?        Ss+  04:03   0:00 bash
root        29  0.0  0.0  18164  1888 ?        Ss   04:04   0:00 bash
root        42  0.0  0.0  15564  1148 ?        R+   04:04   0:00 ps -aux
root@91262536f7c9:/# echo $$
29

39

要与正在运行的容器分离,请使用^P^Q(按住Ctrl,按P,按Q,然后松开Ctrl)。

这里有一个问题:如果容器启动时使用这仅适用 -t-i

如果您有一个正在运行的容器而没有这些选项中的一个(或两个)都已启动,并且附加了docker attach,则需要找到另一种分离方法。根据您选择的选项和正在运行的程序,该程序^C可能会运行,或者可能杀死整个容器。您必须进行试验。

另一个问题是:根据您使用的程序,您的终端,shell,SSH客户端或多路复用器可能会拦截^P^Q(通常是后者)。要测试这是否是问题,请尝试运行或附加--detach-keys z参数。现在,您应该可以通过按来分离z,而无需任何修饰符。如果可行,则说明另一个程序正在干扰。解决此问题的最简单方法是使用参数设置自己的分离序列--detach-keys。(例如,使用退出^K,使用--detach-keys 'ctrl-k'。)或者,您可以尝试禁用对终端或其他干扰程序中按键的拦截。例如,stty start ''stty start undef可能阻止终端拦截^Q 在某些POSIX系统上,尽管我没有发现这有帮助。


2
超级精确的解释,就像一个魅力的工作
米尔·加巴

27

如果没有其他作用,请打开一个新终端,然后:

$ ps aux | grep attach
username  <pid_here>    ..............  0:00 docker attach <CONTAINER_HASH_HERE>
username  <another_pid> ..............  0:00 grep --color=auto attach
$ kill -9 <pid_here>

真是陷阱!谢谢,这是唯一有效的方法。-9没必要。
Heath Raftery

这也会杀死容器-可能取决于设置了哪些标志。
AdamAL

1
请注意,如果显示两个pid,则第一个为父。您应该使用第二个piddocker attach而不是其父对象来杀死它。
joeytwiddle

11

要从容器中取出,只需按住Ctrl并按P+即可Q

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

$ docker container attach "container_name"

9

我遇到了同样的问题,并且ctrl- 无法正常工作,也-- 最终我打开了另一个终端会话,并执行了“ docker stop containerid ”和“ docker start containerid ”,并完成了工作。奇怪的。PQctrlC


如果您使用--rm标志启动容器,则此操作将无效。Ctrl+PCtrl+Q在您使用-it标志启动容器时起作用。
Aswath K '18

4

在同一外壳中,按住ctrl键并按键,p然后q


3
仅当您使用-it标志启动容器时,此方法才有效。
Aswath K '18



0

要停止docker进程并释放端口,请首先使用ctrl- c离开容器出口,然后使用docker ps查找正在运行的容器列表。然后,您可以使用docker容器stop停止该进程并释放其端口。您可以从docker ps命令中找到容器名称,该命令在名称列中提供名称。希望这能解决您的问题。


0

如果您只需要docker进程在后台运行,则可以使用

Ctrl + Z

请注意,这不是真正的分离,它会带来性能损失。(您可以使用bg命令将其返回到前台)。

另一个选择是,如果您不再需要关闭终端,请关闭它。


0

对于遇到同样问题的任何人,我都做到了(即使不设置容器也无法断开容器,即使设置了分离键)……

在启动容器时 docker-compose up -d

而不是docker attach {container name}用来查看拖尾日志...。

尝试docker-compose logs -f {service name} ctrl- c杀死日志尾巴而不杀死您的容器

{service name}是在docker-compose.yml文件中列出的服务.. (例如,当容器名称= elk_logstash_1->服务名称= logstash时)

高温超导


0

更新资料

我通常使用docker attach查看STDOUT显示的内容,以对容器进行故障排除。我刚刚发现docker logs --follow 621a4334f97b,它使我可以看到STDOUT,同时也可以在不影响容器操作的情况下对其进行ctrl + c!正是我一直想要的。

...自然,您需要替换您自己的容器ID。

原始答案

我想让容器继续运行,但是没有通过来启动容器-it。我的解决方案是牺牲我的SSH连接(因为我被SSH到运行容器的计算机中)。终止该ssh会话后,容器保持完整,但使我脱离了容器。

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.