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


当前回答

有两种方法。

与连接

$ sudo docker attach 665b4a1e17b6 #by ID

与执行

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

其他回答

首先,你不能跑

docker run "existing container" command

因为这个命令期待的是一个图像而不是一个容器,它无论如何都会产生一个新的容器(所以不是你想看的那个)

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

我在DEAMON模式下通过supervisor执行命令。

然后执行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

它所做的是允许您“附加”到容器,并提供监控器ctl接口来停止/启动/重新启动和检查日志。 如果这还不够,你可以按Ctrl+D,你会进入一个shell,让你有一个窥探周围,就像它是一个正常的系统。

请同时考虑到这个系统不如没有外壳的容器安全,所以请采取所有必要的步骤来保护您的容器。

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

假设您的/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在任何时候附加,以查看容器内发生了什么。

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

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

Docker运行——name container_name yourimage Docker exec -it container_name bash

由于情况正在发生变化,目前访问正在运行的容器的推荐方式是使用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

有两种方法。

与连接

$ sudo docker attach 665b4a1e17b6 #by ID

与执行

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