为什么"docker attach"会挂起?

Nan*_*iao 52 linux hang docker

我可以ubuntu成功运行容器:

# docker run -it -d ubuntu
3aef6e642327ce7d19c7381eb145f3ad10291f1f2393af16a6327ee78d7c60bb
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
3aef6e642327        ubuntu              "/bin/bash"         3 seconds ago       Up 2 seconds                            condescending_sammet
Run Code Online (Sandbox Code Playgroud)

但执行docker attach挂起:

# docker attach 3aef6e642327
Run Code Online (Sandbox Code Playgroud)

直到我按任意键,例如Enter:

# docker attach 3aef6e642327
root@3aef6e642327:/#
root@3aef6e642327:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
Run Code Online (Sandbox Code Playgroud)

为什么docker attach挂?

更新:

看完评论后,我想我得到了答案:

先决条件:

"docker attach"重用相同的tty,而不是打开新的tty.

(1)执行docker run无守护进程模式:

# docker run -it ubuntu
root@eb3c9d86d7a2:/# 
Run Code Online (Sandbox Code Playgroud)

一切都好,然后运行ls命令:

root@eb3c9d86d7a2:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@eb3c9d86d7a2:/#
Run Code Online (Sandbox Code Playgroud)

(2)docker run以守护进程模式运行:

# docker run -it -d ubuntu
91262536f7c9a3060641448120bda7af5ca812b0beb8f3c9fe72811a61db07fc
Run Code Online (Sandbox Code Playgroud)

实际上,以下内容应该从正在运行的容器中输出到stdout:

root@91262536f7c9:/#
Run Code Online (Sandbox Code Playgroud)

因此执行docker attach似乎挂起,但实际上它正在等待您的输入:

# docker attach 91262536f7c9
ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@91262536f7c9:/#
Run Code Online (Sandbox Code Playgroud)

Fra*_*ere 30

它并没有真正挂起.正如您在下面的注释中所看到的(您正在运行" /bin/bash"作为命令),它似乎是附加时的预期行为.

据我所知,你附加到正在运行的shell,只是stdin/stdout/stderr - 取决于你传递的选项和运行命令 - 将只显示从那一刻进出的内容.(有更多深入知识的人希望能够在更高层次上解释这一点).

正如我在你对你的问题的评论中写的那样,有几个人在docker github repo上打开了一个描述类似行为的问题:

既然你提到了shell,我假设你已经运行了一个shell.attach不会启动新进程,那么连接到正在运行的进程的in /​​ out/err流的预期行为是什么?我没想到这个.当然这是连接到正在运行的shell的预期行为,但它是否可取?

是否可以在docker attach上刷新stdout/stderr,从而强制打印shell提示符,或者它是否比这更复杂?这是我个人在连接到已经运行的shell时"期望"的东西.

如有必要,请随时关闭此问题,我只是觉得有必要记录下来并获得一些反馈.

如果enter您没有开始输入命令,则不会看到额外的空提示行.如果你要跑

$ docker exec -it ubuntu <container-ID-or-name> bash 
Run Code Online (Sandbox Code Playgroud)

<container-ID-or-name>你运行后容器的ID或名称在哪里docker run -it -d ubuntu(所以你的问题是3aef6e642327或condescending_sammet)它会运行一个新的命令,因此没有附加到现有的"stdout问题".

如果你Dockerfile在一个目录中有一个包含:

FROM ubuntu:latest
ADD ./script.sh /timescript.sh 
RUN chmod +x /timescript.sh
CMD ["/timescript.sh"]
Run Code Online (Sandbox Code Playgroud)

script.sh在同一目录中有一个简单的bash脚本,其中包含:

#!/bin/bash

#trap ctrl-c and exit, couldn't get out
#of the docker container once attached
trap ctrl_c INT
function ctrl_c() {
    exit
}

while true; do
    time=$(date +%N)
    echo $time;
    sleep  1;
done
Run Code Online (Sandbox Code Playgroud)

然后构建(在此示例中与Dockerfile和script.sh在同一目录中)并运行它

$ docker build -t nan-xiao/time-test .
..stuff happening...
$ docker run -itd --name time-test nan-xiao/time-test
Run Code Online (Sandbox Code Playgroud)

最后 attach

$ docker attach time-test
Run Code Online (Sandbox Code Playgroud)

您将最终连接到每秒打印出时间的容器.(CTRL-C退出)

例2

或者,如果你有一个Dockerfile包含例如以下内容:

FROM ubuntu:latest
RUN apt-get -y install irssi
ENTRYPOINT ["irssi"]
Run Code Online (Sandbox Code Playgroud)

然后在同一目录中运行:

$ docker build -t nan-xiao/irssi-test .
Run Code Online (Sandbox Code Playgroud)

然后运行它:

$ docker run -itd --name irssi-test nan-xiao/irssi-test
Run Code Online (Sandbox Code Playgroud)

最后

$ docker attach irssi-test
Run Code Online (Sandbox Code Playgroud)

您最终会在irssi没有此特定行为的运行窗口中运行.当然你可以替换irrsi另一个程序.

  • `docker exec -t -i [container] /bin/bash` 是我浏览容器文件系统所需的终端。 (3认同)

mat*_*aly 14

当我尝试连接到由其他人开发并且已经运行守护进程的容器时,我也遇到了这个问题.(在这种情况下,它是LinuxServer的docker transmission镜像).

问题:

发生的事情是终端似乎"挂起",输入任何东西都没有帮助,也不会出现.只会Ctrl-C让我退缩.

docker run,docker start,docker attach都没有成功,结果发现我需要(容器启动后用命令runstart)被执行bash,因为机会是你拉容器不具备的bash已经运行.

解:

docker exec -it <container-id> bash

(你可以找到container-id从跑步docker ps -a).

这将使您进入具有功能性bash的实例root(假设您提取的图像没有进行其他显式设置).

我知道接受的答案也已经捕获了这个,但是我决定发布另一个更简洁明了的答案,因为当我阅读它时,解决方案并没有突然出现.


Bil*_*ang 7

当我运行时docker attach container-name,没有任何输出,甚至Ctrl-c无效。所以,首先尝试

docker attach container-name --sig-proxy=false
Run Code Online (Sandbox Code Playgroud)

然后就ctrl-c可以阻止它。为什么没有输出任何内容?只是因为容器没有输出。实际上我需要进入我的容器并运行一些 shell 命令。所以正确的命令是

docker exec -ti container-name bash
Run Code Online (Sandbox Code Playgroud)