我天真地期望这个命令在一个正在运行的容器中运行一个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登录吗?
14 回答
使用docker 1.3,有一个新命令docker exec . 这允许您输入正在运行的docker:
如果目标是检查应用程序的日志,这篇文章显示启动tomcat并拖尾记录为CMD的一部分 . 主机上使用“docker logs containerid”可以使用tomcat日志 .
http://blog.trifork.com/2013/08/15/using-docker-to-efficiently-create-multiple-tomcat-instances/
运行容器时分配名称很有用 . 您不需要引用container_id .
docker run --name container_name yourimage docker exec -it container_name bash
在开发容器时,也许你像我一样误导了虚拟机 . 我的建议:尽量不要 .
容器就像任何其他过程一样 . 实际上,您可能希望“附加”它们以进行调试(想想/ proc // env或strace -p),但这是一个非常特殊的情况 .
通常你只是“运行”这个过程,所以如果你想修改配置或读取日志,只需创建一个新的容器,并确保通过共享目录,写入stdout来写日志之外的日志(所以docker日志工作)或类似的东西 .
出于调试目的,您可能需要启动shell,然后启动代码,然后按CTRL-p CTRL-q使shell保持原样 . 这样你可以使用以下方法重新连接:
如果你想调试容器,因为它希望它能做到,请尝试调试它:https://serverfault.com/questions/596994/how-can-i-debug-a-docker-container-initialization
实际上有一种方法可以在容器中安装shell .
假设您的
/root/run.sh
启动流程,流程管理员(主管)或其他任何东西 .使用一些gnu-screen技巧创建
/root/runme.sh
:现在,您可以在选项卡0中使用守护进程,并在选项卡1中使用交互式shell .
docker attach
随时查看容器内发生的情况 .另一个建议是在 生产环境 映像的顶部创建一个“开发包”图像,其中包含所有必要的工具,包括此屏幕技巧 .
这是我的解决方案
DOckerfile的一部分:
“initd.sh”的一部分
构建映像后,您有两个使用exec和attach的选项:
docker run --name $ CONTAINER_NAME -dt $ IMAGE_NAME
然后
docker exec -it $ CONTAINER_NAME / bin / bash
并使用
CTRL D分离
docker run --name $ CONTAINER_NAME -dit $ IMAGE_NAME
然后
docker附加$ CONTAINER_NAME
并使用
CTRL P和CTRL Q分离
选项之间的区别在参数 -i
请关注此拉取请求:https://github.com/docker/docker/pull/7409
它实现了即将发布的
docker exec <container_id> <command>
实用程序 . 当这可用时,应该可以例如在正在运行的容器中启动和停止ssh服务 .还有
nsinit
这样做:"nsinit provides a handy way to access a shell inside a running container's namespace",但看起来很难运行 . https://gist.github.com/ubergarm/ed42ebbea293350c30a6由于事情正在变化,目前推荐的访问正在运行的容器的方法是使用
nsenter
.您可以在github repository找到更多相关信息 . 但一般来说你可以像这样使用nsenter:
或者您可以使用包装
docker-enter
:关于这个主题的一个很好的解释可以在JérômePetazzoni的博客文章中找到:Why you don't need to run sshd in your docker containers
不,这是不可能的 . 如果需要,可以使用像
supervisord
这样的东西来获取ssh服务器 . 虽然,我绝对质疑需要 .您可以使用
有两种方法 .
随着附加
有了exec
编辑:现在你可以使用
docker exec -it "id of running container" bash
(doc)以前,这个问题的答案是:
如果你真的必须而且你在调试环境中,你可以这样做:
sudo lxc-attach -n <ID>
注意id必须是完整的(docker ps -notrunc
) .但是,我强烈建议不要这样做 .
注意:
-notrunc
已弃用,很快就会被--no-trunc
取代 .首先,你无法运行
因为这个命令期望一个图像而不是一个容器,它无论如何都会导致产生一个新的容器(所以不是你想看的那个)
我同意这样的事实:对于docker我们应该以不同的方式进行思考(所以你应该找到方法让你不需要登录容器),但我仍然觉得它很有用,这就是我的工作方式周围 .
我在DEAMON模式下通过主管运行我的命令 .
然后我执行我称之为
docker_loop.sh
的内容就是这样:它的作用是它允许你"attach"到容器并被提供
supervisorctl
接口来停止/启动/重启并检查日志 . 如果这还不够,你可以Ctrl+D
然后你会进入一个shell,让你可以看看它是否像普通系统一样 .请注意,该系统不如没有外壳的容器那么安全,因此请采取所有必要步骤来保护容器 .
做就是了
如评论中所述,要从容器中分离而不停止它,请键入Ctrlpthen Ctrlq .