探索Docker容器的文件系统
我已经注意到docker工人,我需要了解容器内发生了什么,或者有什么文件存在。 一个例子是从docker索引下载图像 – 你不知道图像包含什么,所以不可能启动应用程序。
什么是理想的是能够ssh入他们或同等学历。 有没有一个工具来做到这一点,或者是我认为我应该能够做到这一点的docker错误的概念。
方法1:快照
你可以这样评估容器文件系统:
# find ID of your running container: docker ps # create image (snapshot) from container filesystem docker commit 12345678904b5 mysnapshot # explore this filesystem using bash (for example) docker run -t -i mysnapshot /bin/bash
这样,您就可以在精确的时刻评估正在运行的容器的文件系统。 容器仍在运行,不包括未来的更改。
您可以稍后使用(正在运行的容器的文件系统不受影响!)删除快照:
docker rmi mysnapshot
方法2:ssh
如果您需要连续访问,则可以将sshd安装到您的容器并运行sshd守护进程:
docker run -d -p 22 mysnapshot /usr/sbin/sshd -D # you need to find out which port to connect: docker ps
这样,你可以运行你的应用程序使用SSH(连接并执行你想要的)。
更新 – 方法3:nsenter
使用nsenter
,请参阅http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/
简短的版本是:使用nsenter,即使该容器不运行SSH或任何一种特殊用途的守护进程
更新 – 方法4:docker执行
Docker版本1.3(最新,您可能需要使用docker apt repo来安装截至2014年11月的最新版本)支持与nsenter
类似的新命令exec
。 该命令可以在已经运行的容器中运行新的进程(容器必须已经运行了PID 1进程)。 您可以运行/bin/bash
来浏览容器状态:
docker exec -t -i mycontainer /bin/bash
请参阅Docker命令行文档
您可以将您的容器的文件系统存档到tar文件中:
docker export adoring_kowalevski > contents.tar
即使您的容器已停止,并且没有像/bin/bash
类的任何shell程序,这种方法也能正常工作。 我的意思是像来自Docker文档的 hello-world一样的图像。
更新:
这个命令应该让你探索一个正在运行的docker容器 :
docker exec -it name-of-container bash
一旦在里面做:
ls -lsa
或任何其他bash命令,如:
cd ..
这个命令应该让你探索一个docker镜像 :
docker run --rm -it --entrypoint=/bin/bash name-of-image
一旦在里面做:
ls -lsa
或任何其他bash命令,如:
cd ..
-it
代表交互…和tty
容器的文件系统位于docker的数据文件夹中,通常在/ var / lib / docker中。 为了启动并检查正在运行的容器文件系统,请执行以下操作:
hash=$(docker run busybox) cd /var/lib/docker/aufs/mnt/$hash
而现在的工作目录是容器的根。
在运行Docker 1.3.1的 Ubuntu 14.04上,我在主机上的以下目录中find了容器根文件系统:
/var/lib/docker/devicemapper/mnt/<container id>/rootfs/
完整的Docker版本信息:
Client version: 1.3.1 Client API version: 1.15 Go version (client): go1.3.3 Git commit (client): 4e9bbfa OS/Arch (client): linux/amd64 Server version: 1.3.1 Server API version: 1.15 Go version (server): go1.3.3 Git commit (server): 4e9bbfa
我使用另一个脏窍门是aufs / devicemapper不可知的。
我看容器正在运行的命令,如docker ps
,如果它是一个Apache或java
我只是做以下几点:
sudo -s cd /proc/$(pgrep java)/root/
瞧你在容器里面
基本上你可以作为root cd进入/proc/<PID>/root/
文件夹,只要该进程是由容器运行的。 谨慎符号链接将无法使用该模式。
容器创build之前:
如果您要探索安装在容器内的图像的结构,您可以执行此操作
sudo docker image save image_name > image.tar tar -xvf image.tar
这会给你一个图像的所有图层及其在json文件中的configuration的可见性。
在创build容器之后:
为此,上面已经有很多答案。 我的首选方法是 –
docker exec -t -i container /bin/bash
对我来说,这个效果很好(感谢最后的意见,指出目录/ var / lib / docker / ):
chroot /var/lib/docker/containers/2465790aa2c4*/root/
在这里, 2465790aa2c4是正在运行的容器的短ID(由docker ps显示),后面是星号。
除非你的容器不是一个真正的Linux系统,否则表决得票最多的答案是好的。
许多容器(尤其是基于go的容器)没有任何标准二进制文件(no / bin / bash,/ bin / sh)。 在这种情况下,您将需要直接访问实际的容器文件:
奇迹般有效:
name=<name> dockerId=$(docker inspect -f {{.Id}} $name) cd /var/lib/docker/devicemapper/mnt/$dockerId
注意:您需要以root身份运行它。
对于docker aufs驱动程序:
脚本将find容器根目录(在docker 1.7.1和1.10.3上testing)
if [ -z "$1" ] ; then echo 'docker-find-root $container_id_or_name ' exit 1 fi CID=$(docker inspect --format {{.Id}} $1) if [ -n "$CID" ] ; then if [ -f /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id ] ; then F1=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id) d1=/var/lib/docker/aufs/mnt/$F1 fi if [ ! -d "$d1" ] ; then d1=/var/lib/docker/aufs/diff/$CID fi echo $d1 fi
对于已经运行的容器,你可以这样做:
dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name]) cd /var/lib/docker/btrfs/subvolumes/$dockerId
您需要成为根目录才能进入该目录。 如果您不是root用户,请在运行该命令之前尝试“sudo su”。
编辑:在v1.3之后,请参阅Jiri的回答 – 更好。
当容器实际启动时,最有效的答案是为我工作,但是当它不可能运行,并且你想要从容器中复制文件,这已经保存在我之前:
docker cp <container-name>:<path/inside/container> <path/on/host/>
由于docker cp( 链接 ),您可以直接从容器中复制文件系统的任何其他部分。 例如,恢复容器内的所有文件:
mkdir /tmp/container_temp docker cp example_container:/ /tmp/container_temp/
请注意,您不需要指定要recursion复制。
尝试使用
docker exec -it <container-name> /bin/bash
有可能是没有实施bash。 为此你可以使用
docker exec -it <container-name> sh
在新版本的Docker上,你可以运行docker exec [container_name]
,它在你的容器中运行一个shell
因此,要获取容器中所有文件的列表,只需运行docker exec [container_name] ls
我最好的方法来了解容器内部发生的事情是:
-
揭露-p 8000
docker run -it -p 8000:8000 image
-
在里面启动服务器
python -m SimpleHTTPServer
另一个诀窍是使用primefaces工具来做类似的事情:
mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt
Docker镜像将被挂载到/ path / to / mnt中供您检查。
这个答案会帮助那些想要探索Docker卷文件系统的人(比如我自己),即使容器没有运行。
列出正在运行的docker容器:
docker ps
=> CONTAINER ID“4c721f1985bd”
查看本地物理机上的docker卷挂载点( https://docs.docker.com/engine/tutorials/dockervolumes/ ):
docker inspect -f {{.Mounts}} 4c721f1985bd
=> [{/ tmp / container-garren / tmp true rprivate}]
这告诉我本地物理机器目录/ tmp / container-garren被映射到/ tmp docker卷目的地。
知道本地物理机器目录(/ tmp / container-garren)意味着我可以浏览文件系统是否运行docker容器。 这对于帮助我发现有一些残留的数据,即使在容器没有运行之后,这些数据不应该持续存在也是至关重要的。
你可以在这个容器里运行一个bash: $ docker run -it ubuntu /bin/bash
如果您使用AUFS存储驱动程序,则可以使用我的docker-layer脚本来查找任何容器的文件系统根(mnt)和读写层:
# docker-layer musing_wiles rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f mnt : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f