探索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

我最好的方法来了解容器内部发生的事情是:

  1. 揭露-p 8000

     docker run -it -p 8000:8000 image 
  2. 在里面启动服务器

     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