是否有可能在正在运行的容器中启动一个shell会话(不使用ssh)
我天真地期待这个命令在运行的容器中运行一个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服务器并通过SSHlogin?
编辑:现在你可以使用docker exec -it "id of running container" bash
( doc )
以前,这个问题的答案是:
如果你真的必须和你在一个debugging环境中,你可以这样做: sudo lxc-attach -n <ID>
请注意,id需要是完整的( docker ps -notrunc
)。
不过,我强烈build议不要这样做。
注意: -notrunc
已经被弃用了,它将很快被replace为--no-trunc
。
随着docker1.3,有一个新的命令docker exec
。 这可以让你input一个正在运行的docker:
docker exec -it "id of running container" bash
由于事情正在变化,目前推荐的访问正在运行的容器的方式是使用nsenter
。
你可以在这个github仓库find更多的信息。 但一般来说,你可以像这样使用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的博客文章中find: 为什么你不需要在你的docker容器中运行sshd
做就是了
docker attach container_name
如注释中所述,要从容器中分离而不停止,请键入Ctrl + p然后Ctrl + q 。
首先你不能跑
docker run "existing container" command
因为这个命令是期待一个图像而不是一个容器 ,反正会导致一个新的容器被产生(所以不是你想要看的那个)
我同意这样一个事实,即docker工人应该以不同的方式思考(所以你应该想方设法让你不需要login容器),但是我仍然觉得它很有用,这就是我的工作方式周围。
我在DEAMON模式下通过pipe理员运行我的命令。
然后我执行我所说的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,这样你就可以像一个普通的系统一样偷看。
请注意,这个系统不像没有shell的容器那么安全,所以要采取一切必要的步骤来保护你的容器。
请留意这个请求: https : //github.com/docker/docker/pull/7409
其中实现了即将发布的docker exec <container_id> <command>
实用程序。 当这是可用的,应该可以例如启动和停止正在运行的容器内的ssh服务。
还有nsinit
可以做到这一点: “nsinit提供了一种方便的方式来访问正在运行的容器名称空间内的一个shell” ,但是看起来很难运行。 https://gist.github.com/ubergarm/ed42ebbea293350c30a6
实际上有一种方法在容器中有一个壳。
假设你的/root/run.sh
启动了进程,进程pipe理器(主pipe)或者其他任何东西。
用一些gnu-screen的技巧创build/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
随时docker attach
看看容器内发生了什么。
另一个build议是在生产图像顶部创build一个“开发包”图像,并使用所有必要的工具,包括这个屏幕技巧。
这是我的解决scheme
部分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
图像build立后,你有两个选项使用exec和attach:
- 与exec(我使用),运行:
docker运行 – 名称$ CONTAINER_NAME -dt $ IMAGE_NAME
然后
docker执行程序-it $ CONTAINER_NAME / bin / bash
并使用
CTRL + D分离
- 附带,运行:
docker运行 – 名称$ CONTAINER_NAME – $ $ IMAGE_NAME
然后
docker工人附加$ CONTAINER_NAME
并使用
CTRL + P和CTRL + Q分离
选项之间的区别在参数-i中
有两种方法。
随附
$ sudo docker attach 665b4a1e17b6 #by ID
与执行
$ sudo docker exec - -t 665b4a1e17b6 #by ID
如果目标是检查应用程序的日志,这篇文章展示了启动tomcat和拖尾日志作为CMD的一部分。 tomcat日志在主机上使用'docker logs containerid'。
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
也许你在开发容器的时候,像我自己一样误导了VM。 我的build议:尽量不要。
容器就像其他过程一样。 确实,你可能想“附加”到他们的debugging目的(想到/ proc / env或strace -p),但这是一个非常特殊的情况。
通常你只是“运行”进程,所以如果你想修改configuration或读取日志,只需创build一个新的容器,并确保通过共享目录写入到stdout(所以docker日志工作)或类似的东西。
出于debugging的目的,你可能想要启动一个shell,然后是你的代码,然后按CTRL-P + CTRL-q使shell保持不变。 这样你可以重新使用:
docker attach <container_id>
如果你想debugging容器,因为它正在做一些你没有想到的事情,请尝试debugging它: https : //serverfault.com/questions/596994/how-can-i-debug-a-docker-container -初始化
不,这是不可能的。 如果需要的话,使用像supervisord
这样的东西来获得一个SSH服务器。 虽然,我当然质疑需要。