【问题标题】:How do you attach and detach from Docker's process?你如何附加和分离 Docker 的进程?
【发布时间】:2013-11-10 09:13:29
【问题描述】:

我可以附加到 docker 进程,但 Ctrl+c 无法从中分离。 exit 基本上停止了这个过程。

让进程运行、偶尔附加到它以进行一些更改然后分离的推荐工作流程是什么?

【问题讨论】:

  • 使用nsenter时,我只是Ctrl-D退出。
  • 关闭xtermkonsole 等是否有效?它对我有用(我变得超然)。

标签: docker


【解决方案1】:

如果 --sig-proxy=false 方法不起作用,那么您还可以使用以下方法更改转义序列:

docker attach --detach-keys="<sequence>" <container_name or id> 

例如,我想使用“ctrl-c”分离容器,然后我可以使用以下方法附加容器:

docker attach --detach-keys="ctrl-c" <container_name or id>

的格式可以是字母 [a-Z],也可以是 ctrl- 与以下任意组合:

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

有关更多信息,另请参阅 -> Override the detach sequence

【讨论】:

    【解决方案2】:

    我发现documentation 关于附加和分离有点复杂。

    我尝试了不同的选项来启动一个容器并从另一个终端附加到它。下表总结了结果:

    具有以下列含义:

    • -d - 是否使用 docker run -d 选项
    • --sig-proxy - 是 docker attach --sig-proxy=true|false 过去不使用的选项
    • --no-stdin - 是 docker attach [--no-stdin] 过去不使用的选项
    • keys - docker 是否将输入键发送到容器化应用程序
    • ^C - 当用户按下 Ctrl+C 时发生了什么
    • ^P ^Q - 当用户按下 Ctrl+P Ctrl+Q 时发生了什么

    有几个发现:

    • 附件行为不依赖于-d 选项,而是来自-i-t

    • 您可以考虑将列附加到从另一个终端(例如docker attach --sig-proxy=false,您可以更改连接选项)或从当前终端(但您不能更改连接选项;--sig-proxy=true)到容器的连接

    • 分离取决于运行选项,可以通过三种方式完成:

      1. docker run [-i|-t] 并通过 docker attach --sig-proxy=false CONT 从另一个终端连接 -> 按 Ctrl+C
      2. docker run -it 并通过 docker attach 从另一个终端连接 -> 按 Ctrl+P Ctrl+Q
      3. docker run -it 并通过 docker attach --no-stdin 从另一个终端连接 -> 按 Ctrl+C

    (当然,您应该为容器名称或图像等命令提供其他必要的参数)

    附:我用-i-t(只有其中一个)尝试了不同的场景,但没有得到行为上的差异。我看到@ken-cochrane 提供了以下内容:

    docker run -i → 不能用 ^P^Q 分离;会破坏标准输入

    但我没有成功复制这个。

    【讨论】:

      【解决方案3】:

      要从正在运行的容器中分离,请使用 ^P^Q(按住 Ctrl,按 P,按 Q kbd>,松开 Ctrl)。

      有一个问题:这仅在容器以 -t-i 启动时才有效。

      如果您有一个正在运行的容器在没有这些选项中的一个(或两个)的情况下启动,并且您使用docker attach 附加,则需要找到另一种分离方式。根据您选择的选项和正在运行的程序,^C 可能会起作用,也可能会杀死整个容器。您必须进行实验。

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

      【讨论】:

      • 指定容器必须以-t-i 启动...谢谢!
      【解决方案4】:

      更新

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

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

      原答案

      我想让容器继续运行,但在没有使用-it 启动容器的情况下连接。我的解决方案是牺牲我的 SSH 连接(因为我是通过 SSH 连接到运行容器的机器上)。终止该 ssh 会话使容器完好无损,但使我与它分离。

      【讨论】:

        【解决方案5】:

        要在不退出 shell 的情况下分离 tty,请使用转义序列 Ctrl+P 后跟 Ctrl+Q kbd>。更多详情here.

        来自this source的其他信息:

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

        【讨论】:

        • 如果它确实按照文档中的描述工作,这将是一个很好的答案。
        • 我发现即使使用 -it 运行,如果您还使用清理标志 (--rm) 启动容器,分离序列也会失败。这对某些人来说可能很明显,但它比我想承认的更常让我感到痛苦。
        • 另一种选择是关闭终端窗口或 cmd-w :)
        • 您可以设置可配置的分离键,例如"detachKeys": "ctrl-a,a" 在你的 .docker/config.json 文件中或--detach-keys "ctrl-a,a" 在带有附加等的命令行中。
        • Ctrl + Z 不会分离;它只是该过程的背景。它与分离不同,会带来性能损失。
        【解决方案6】:

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

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

        sudo docker exec -ti [CONTAINER-ID] bash

        会用bash shell启动一个新进程,你可以直接用Ctrl+C退出它,不会影响原来的进程。

        【讨论】:

        • 这个成功了,你可以在完成后输入“exit”而不影响原来的过程。
        • 这是附加到正在运行的容器的好方法。但是如果(比如说)我在容器中运行了一些进程并且我想重新启动该进程怎么办?啊,我可以杀死旧进程,重新启动新进程,然后使用 C-p,C-q,因为它是交互式 tty,所以它可以工作。我也喜欢 --sig-proxy=false 方法,但它更通用,不会强制中断当前进程。
        • “attach”跟Docker有特定的含义,exec不是。
        【解决方案7】:

        对于遇到与我相同的问题的任何人(即使在设置分离键的情况下也无法在不杀死容器的情况下分离)......

        使用docker-compose up -d 启动容器时

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

        try docker-compose logs -f {service name} ctrl-c 杀死日志尾部而不杀死你的容器

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

        HTH

        【讨论】:

          【解决方案8】:

          如果你只需要 docker 进程进入后台你可以使用

          Ctrl + Z

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

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

          【讨论】:

            【解决方案9】:

            我遇到了同样的问题,ctrl-PQ 不起作用,ctrl-C...最终我打开了另一个终端会话,我做了“docker stop containerid”和“docker start containerid”,它完成了工作.很奇怪。

            【讨论】:

            • 如果您使用--rm 标志启动容器,这将不起作用。如果您使用 -it 标志启动容器,Ctrl+PCtrl+Q 可以工作。
            【解决方案10】:

            在同一个 shell 中,按住 ctrl 键并按 p 然后按 q

            【讨论】:

            • 这仅在您使用 -it 标志启动容器时有效。
            【解决方案11】:

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

            【讨论】:

              【解决方案12】:

              也请查看the --sig-proxy option:

              docker attach --sig-proxy=false 304f5db405ec
              

              然后用CTRL+c分离

              【讨论】:

              • 要尝试从 run 而不是 attach 开始,我尝试了:docker run -ti --sig-proxy=false busybox top 这似乎不起作用,进程被 ctrl-c 杀死,但从 docker run -t -sig-proxy=false busybox top 开始似乎可以工作并启用退出使用 ctrl-c
              • Ctrl-c 也会停止容器。
              • 这是此处列出的解决方案中唯一适用于运行 Docker 19.03.5 的 Debian 9 服务器的解决方案。问题是,为什么这不是附加命令的默认设置?这似乎是最常见的用例。
              • Ctrl-p、Ctrl-q 序列对我不起作用(从 docker container attach xyz 开始).. 但这确实有效。谢谢@czerasz
              【解决方案13】:
              1. 打开一个新终端
              2. 找到正在运行的容器Id docker ps
              3. 杀死容器docker kill ${containerId}

              【讨论】:

                【解决方案14】:

                我在 Mac 上,出于某种原因,Ctrl-p Ctrl-q 会仅当我还持有 Shift

                时才有效

                【讨论】:

                  【解决方案15】:

                  要从容器中分离,您只需按住 Ctrl 并按 P + Q

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

                  $ docker container attach "container_name"
                  

                  【讨论】:

                    【解决方案16】:

                    当其他方法都不起作用时,打开一个新的终端然后:

                    $ 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 不是必需的。
                    • 这也会杀死容器——可能取决于设置了哪些标志。
                    • 请注意如果显示了两个 pid,那么第一个是父进程。您应该使用第二个 pid 杀死 docker attach 而不是它的父级。
                    【解决方案17】:

                    我觉得这要视情况而定。以下面的容器为例:

                    # 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 kbd>。

                    (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
                    

                    然后再次登录容器,你会看到前面docker exec命令中的bash进程仍然存在(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
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-06-24
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-02-26
                      相关资源
                      最近更新 更多