348

我天真地期待这个命令在一个正在运行的容器中运行一个 bash shell:

docker run "id of running container" /bin/bash

看起来不可能,我收到错误消息:

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

因此,如果我想在正在运行的容器中运行 bash shell(例如,用于诊断目的)

我是否必须在其中运行 SSH 服务器并通过 ssh 登录?

4

15 回答 15

617

在 docker 1.3 中,有一个新命令docker exec。这允许您输入正在运行的 docker:

docker exec -it "id of running container" bash
于 2014-10-21T21:42:19.367 回答
291

编辑:现在你可以使用docker exec -it "id of running container" bashdoc

以前,这个问题的答案是:

如果您确实必须并且您处于调试环境中,您可以这样做:sudo lxc-attach -n <ID> 请注意,id 必须是完整的 ( docker ps -notrunc)。

但是,我强烈建议不要这样做。

注意:-notrunc已弃用,很快就会被替换--no-trunc

于 2013-07-29T18:54:06.453 回答
15

做就是了

docker attach container_name

如评论中所述,要从容器中分离而不停止它,请键入Ctrlpthen Ctrlq

于 2014-05-12T09:59:23.843 回答
10

由于情况正在发生变化,目前推荐的访问正在运行的容器的方法是使用nsenter.

您可以在此github 存储库中找到更多信息。但总的来说,您可以像这样使用 nsenter:

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

或者您可以使用包装器docker-enter

docker-enter <container_name_or_ID>

可以在 Jérôme Petazzoni 的博客条目中找到关于该主题的一个很好的解释: Why you don't need to run sshd in your docker containers

于 2014-08-20T07:23:37.497 回答
8

你不能跑的第一件事

docker run "existing container" command

因为这个命令需要一个图像而不是一个容器,它无论如何都会导致一个新的容器被生成(所以不是你想看的那个)

我同意使用 docker 我们应该推动自己以不同的方式思考这一事实(所以你应该找到不需要登录容器的方法),但我仍然觉得它很有用,这就是我的工作方式周围。

我在 DEAMON 模式下通过主管运行我的命令。

然后我执行我所说docker_loop.sh 的内容几乎是这样的:

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

它的作用是允许您“附加”到容器并显示supervisorctl停止/启动/重新启动和检查日志的界面。如果这还不够,您可以Ctrl+D并且您将进入一个外壳,让您可以像普通系统一样四处看看。

请务必考虑到该系统不如没有外壳的容器安全,因此请采取所有必要步骤来保护您的容器。

于 2014-01-05T10:21:04.983 回答
5

密切关注这个拉取请求:https ://github.com/docker/docker/pull/7409

它实现了即将推出的docker exec <container_id> <command>实用程序。当它可用时,应该可以在运行的容器中启动和停止 ssh 服务。

nsinit可以这样做:“nsinit 提供了一种方便的方式来访问正在运行的容器的命名空间内的 shell”,但它看起来很难运行。 https://gist.github.com/ubergarm/ed42ebbea293350c30a6

于 2014-09-03T11:01:08.213 回答
3

您可以使用

docker exec -it <container_name> bash
于 2018-05-09T00:36:14.597 回答
2

这是我的解决方案

在 Dockerfile 中:

# ...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

initd.sh文件中

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

构建映像后,您有两个选项使用execor attach

  1. 使用 exec (首选)并运行:

    docker run --name $CONTAINER_NAME -dt $IMAGE_NAME
    

    然后

    docker exec -it $CONTAINER_NAME /bin/bash
    

    并使用CTRL+D分离

  2. 使用附加并运行:

    docker run --name $CONTAINER_NAME -dit $IMAGE_NAME
    

    然后

    docker attach $CONTAINER_NAME
    

    并使用CTRL+PCTRL+Q分离

    注意:选项之间的区别在于参数-i

于 2014-11-26T09:36:07.733 回答
1

实际上有一种方法可以在容器中放置一个外壳。

假设您/root/run.sh启动了流程、流程管理器(主管)或其他任何东西。

/root/runme.sh使用一些 gnu-screen 技巧进行创建:

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

现在,您在选项卡 0 中拥有守护进程,在选项卡 1 中拥有交互式 shell。docker attach随时查看容器内发生的情况。

另一个建议是在生产映像之上创建一个“开发包”映像,其中包含所有必要的工具,包括这个屏幕技巧。

于 2014-05-31T03:29:27.950 回答
1

有两种方法。

带附件

$ sudo docker attach 665b4a1e17b6 #by ID

与执行

$ sudo docker exec - -t 665b4a1e17b6 #by ID
于 2016-03-29T18:41:29.467 回答
0

如果目标是检查应用程序的日志,这篇文章显示了启动 tomcat 并将日志作为 CMD 的一部分。使用 'docker logs containerid' 在主机上可以使用 tomcat 日志。

http://blog.trifork.com/2013/08/15/using-docker-to-efficiently-create-multiple-tomcat-instances/

于 2013-10-01T16:41:38.757 回答
0

运行容器时分配名称很有用。您不需要参考 container_id。

docker run --name container_name yourimage docker exec -it container_name bash

于 2017-08-18T07:42:52.847 回答
0

首先,通过以下方式获取所需容器的容器 ID

docker ps

你会得到这样的东西:

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                          PORTS                    NAMES
3ac548b6b315        frontend_react-web     "npm run start"     48 seconds ago      Up 47 seconds                   0.0.0.0:3000->3000/tcp   frontend_react-web_1

现在复制此容器 ID 并运行以下命令:

docker exec -it container_id sh

docker exec -it 3ac548b6b315 sh

于 2019-04-22T11:47:33.387 回答
-2

也许你在开发容器时像我一样被误导了考虑虚拟机。我的建议:尽量不要。

容器就像任何其他进程一样。实际上,您可能希望“附加”到它们以进行调试(想想 /proc//env 或 strace -p ),但这是一个非常特殊的情况。

通常你只是“运行”这个过程,所以如果你想修改配置或读取日志,只需创建一个新容器并确保你通过共享目录将日志写入它之外,写入标准输出(所以 docker logs 工作)或类似的东西。

出于调试目的,您可能想要启动一个 shell,然后是您的代码,然后按 CTRL-p + CTRL-q 以保持 shell 完好无损。这样,您可以使用以下方法重新连接:

docker attach <container_id>

如果您想调试容器,因为它正在做您没想到它会做的事情,请尝试调试它:https ://serverfault.com/questions/596994/how-can-i-debug-a-docker-container -初始化

于 2014-05-26T09:08:27.430 回答
-4

不,这是不可能的。如果需要,请使用类似supervisord获取 ssh 服务器的东西。虽然,我肯定质疑这种需要。

于 2013-07-28T18:48:51.987 回答