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


当前回答

不。这是不可能的。如果需要的话,可以使用类似于supervisor ord的工具来获取ssh服务器。不过,我对这种必要性表示怀疑。

其他回答

由于情况正在发生变化,目前访问正在运行的容器的推荐方式是使用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的博客上找到: 为什么不需要在docker容器中运行sshd

这是我的解决方案

在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

镜像构建后,你有两个选择使用exec或attach:

使用exec(首选)并运行: ——name $CONTAINER_NAME -dt $IMAGE_NAME 然后 - $CONTAINER_NAME /bin/bash 并使用CTRL + D分离 使用attach并运行: ——name $CONTAINER_NAME -dit $IMAGE_NAME 然后 附加$CONTAINER_NAME 并使用CTRL + P和CTRL + Q分离 注意:选项之间的区别是参数-i

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

docker exec -it "id of running container" bash

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

假设您的/root/run.sh启动进程、进程管理器(管理器)或任何东西。

使用一些gnu屏幕技巧创建/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'

现在,在tab 0中有守护进程,在tab 1中有交互式shell。Docker在任何时候附加,以查看容器内发生了什么。

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

编辑:现在你可以使用docker exec -它“运行容器的id”bash (doc)

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

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

然而,我强烈建议不要这样做。

注意:-notrunc已弃用,它将很快被——no-trunc取代。