是否可以在正在运行的容器中启动shell会话(没有ssh)

时间:2013-07-28 00:05:06

标签: docker

我天真地期望这个命令在正在运行的容器中运行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登录?

15 个答案:

答案 0 :(得分:599)

使用docker 1.3,有一个新命令docker exec。这允许您输入正在运行的泊坞窗:

docker exec -it "id of running container" bash

答案 1 :(得分:261)

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

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

如果您真的必须且处于调试环境中,则可以执行此操作:sudo lxc-attach -n <ID> 请注意,id必须是完整的(docker ps -notrunc)。

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

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

答案 2 :(得分:14)

只做

docker attach container_name

如评论中所述,要从容器中分离而不停止,请键入 Ctrl p 然后 Ctrl q

答案 3 :(得分:10)

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

您可以找到有关此github repository的更多信息。但一般来说,你可以像这样使用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ômePetazzoni的博客文章中找到: Why you don't need to run sshd in your docker containers

答案 4 :(得分: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,然后你会进入一个shell,让你可以看看它是否像普通系统一样。

请注意,此系统不如没有外壳的容器那么安全,因此请采取所有必要步骤来保护容器。

答案 5 :(得分:4)

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

实现即将发布的docker exec <container_id> <command>实用程序。当这可用时,应该可以例如在正在运行的容器中启动和停止ssh服务。

还有nsinit来执行此操作:&#34; nsinit提供了一种方便的方法来访问正在运行的容器的命名空间&#34; 中的shell,但它看起来很难跑。 https://gist.github.com/ubergarm/ed42ebbea293350c30a6

答案 6 :(得分:3)

您可以使用

project
  - .git
  - src
  - dist
    - my files and folders

答案 7 :(得分:1)

实际上有一种方法可以在容器中安装shell。

假设您的/root/run.sh启动流程,流程经理(主管)或其他任何内容。

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

# 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随时查看容器内发生的情况。

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

答案 8 :(得分:1)

这是我的解决方案

DOckerfile的一部分:

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

&#34; initd.sh&#34;

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

构建映像后,您有两个使用exec和attach的选项:

  1. 使用exec(我使用),运行:
  2. docker run --name $ CONTAINER_NAME -dt $ IMAGE_NAME

    然后

    docker exec -it $ CONTAINER_NAME / bin / bash

    并使用

    CTRL + D分离

    1. with attach,运行:
    2. docker run --name $ CONTAINER_NAME -dit $ IMAGE_NAME

      然后

      docker attach $ CONTAINER_NAME

      并使用

      CTRL + P和CTRL + Q分离

      选项之间的差异在参数 -i

答案 9 :(得分:1)

有两种方式。

附加

$ sudo docker attach 665b4a1e17b6 #by ID

使用exec

$ sudo docker exec - -t 665b4a1e17b6 #by ID

答案 10 :(得分:1)

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

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

答案 11 :(得分:0)

如果目标是检查应用程序的日志,则此帖子显示启动tomcat并将日志作为CMD的一部分进行拖尾。 tomcat日志在主机上使用'docker logs containerid'。

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

答案 12 :(得分: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

答案 13 :(得分:-2)

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

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

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

出于调试目的,您可能需要启动shell,然后启动代码,然后按CTRL-p + CTRL-q使shell保持原样。这样您就可以使用以下方法重新附加:

docker attach <container_id>

如果您想调试容器,因为它正在执行您不希望它执行的操作,请尝试对其进行调试:https://serverfault.com/questions/596994/how-can-i-debug-a-docker-container-initialization

答案 14 :(得分:-4)

没有。这是不可能的。如果需要,可以使用类似supervisord的内容来获取ssh服务器。虽然,我绝对质疑需要。