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

例如,如果我试着:

Docker运行-i -t foo /bin/bash或 Docker附加foo(用于已经运行的容器)

两者都把我带到集装箱中的一个终端,我如何在不停止它的情况下退出集装箱的终端?

exit和CTR+C都停止容器。


当前回答

我深入研究了这个问题,上面所有的答案都部分正确。这完全取决于容器是如何启动的。当容器启动时,可以归结为:

分配了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]$    

第三种方法

但是有一种方法可以在不杀死容器的情况下分离;你需要另一个外壳。总而言之,在另一个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]$

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

其他回答

如果你只想看到容器中运行的进程的输出,你可以做一个简单的docker container logs -f <容器id>。

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

当你运行docker attach时,你可以使用——detach-keys选项来覆盖默认的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>"标志。<序列>的格式可以是字母[a- z],也可以是ctrl-和以下任意组合:

a-z(一个小写字母) @(@号) [(左括号) \(两个反斜杠) _(下划线) ^(脱字符号)

这些a、ctrl-a、X或ctrl-\\值都是有效键序列的示例。若要为所有容器配置不同的配置默认密钥序列,请参阅配置文件部分。

注意:从docker版本1.10+开始工作(在回答这个问题时,当前版本是18.03)

我深入研究了这个问题,上面所有的答案都部分正确。这完全取决于容器是如何启动的。当容器启动时,可以归结为:

分配了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]$    

第三种方法

但是有一种方法可以在不杀死容器的情况下分离;你需要另一个外壳。总而言之,在另一个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]$

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

尝试按CTRL+P,CTRL+Q将交互模式转换为守护模式。

如果这不起作用,你通过docker attach附加,你可以通过杀死docker attach进程来分离。

更好的方法是使用sig-proxy参数来避免将CTRL+C传递给容器:

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

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

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