探索Docker容器的文件系统

时间:2013-12-28 10:29:02

标签: linux docker filesystems

我注意到docker我需要了解容器内发生的事情或者那里存在的文件。一个例子是从docker索引下载图像 - 你不知道图像包含什么,因此无法启动应用程序。

什么是理想的是能够ssh到他们或同等。有没有一个工具可以做到这一点,或者我认为码头工作者的错误认为我应该能够做到这一点。

27 个答案:

答案 0 :(得分:573)

方法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,你可以获得一个shell   现有容器,即使该容器不运行SSH或任何类型   特殊用途守护程序

更新 - 方法4:docker exec

Docker 1.3版(最新版本,您可能需要使用docker apt repo来安装自2014年11月起的最新版本)支持与exec类似的新命令nsenter。此命令可以在已经运行的容器中运行新进程(容器必须已经运行PID 1进程)。您可以运行/bin/bash来探索容器状态:

docker exec -t -i mycontainer /bin/bash

请参阅Docker command line documentation

答案 1 :(得分:187)

更新:探索!

此命令可让您探索正在运行的docker容器

docker exec -it name-of-container bash

docker-compose中的等价物是:

docker-compose exec web bash

(在这种情况下,web是服务名称,默认情况下它是tty。)

进入内部后:

ls -lsa

或任何其他bash命令,如:

cd ..

此命令可让您探索泊坞窗图片

docker run --rm -it --entrypoint=/bin/bash name-of-image

一旦进入内部:

ls -lsa

或任何其他bash命令,如:

cd ..

-it代表互动......和tty。

此命令可让您检查正在运行的docker容器或图像

docker inspect name-of-container-or-image

您可能希望这样做并找出其中是否有bashsh。在json返回中查找入口点或cmd。

请参阅docker exec documentation

请参阅docker-compose exec documentation

请参阅docker inspect documentation

答案 2 :(得分:135)

您可以存档您的容器'文件系统到tar文件:

docker export adoring_kowalevski > contents.tar

即使您的容器已停止且没有任何shell程序(如/bin/bash),这种方式仍然有效。我的意思是来自Docker documentation的hello-world图像。

答案 3 :(得分:40)

容器的文件系统位于docker的数据文件夹中,通常位于/ var / lib / docker中。要启动和检查正在运行的容器文件系统,请执行以下操作:

hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash

现在当前的工作目录是容器的根目录。

答案 4 :(得分:21)

在创建容器之前:

如果要探索容器中安装的图像的结构,可以执行

sudo docker image save image_name > image.tar
tar -xvf image.tar

这将使您可以看到图像的所有图层及其在json文件中的配置。

创建容器后:

为此,上面已有很多答案。我喜欢的方式 这将是 -

docker exec -t -i container /bin/bash

答案 5 :(得分:17)

在运行 Docker 1.3.1 Ubuntu 14.04 上,我在以下目录中的主机上找到了容器根文件系统:

/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

答案 6 :(得分:14)

当容器实际启动时,最受欢迎的答案是为我工作,但是当无法运行时,例如你想要从容器中复制文件时,这已经保存了我:

docker cp <container-name>:<path/inside/container> <path/on/host/>

感谢docker cp(link),您可以直接从容器中复制,因为它是文件系统的任何其他部分。 例如,恢复容器内的所有文件:

mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/

请注意,您无需指定要递归复制。

答案 7 :(得分:11)

除非您的容器不是真正的Linux系统,否则投票最多的答案是好的。

许多容器(尤其是基于go的容器)没有任何标准二进制文件(无/bin/bash/bin/sh)。在这种情况下,您需要直接访问实际的容器文件:

像魅力一样:

name=<name>
dockerId=$(docker inspect -f {{.Id}} $name)
mountId=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$dockerId/mount-id)
cd /var/lib/docker/aufs/mnt/$mountId

注意:您需要以root身份运行它。

答案 8 :(得分:10)

尝试使用

docker exec -it <container-name> /bin/bash

可能没有实现bash。为此你可以使用

docker exec -it <container-name> sh

答案 9 :(得分:4)

对我来说,这个很好用(感谢最后的评论指出目录 / var / lib / docker / ):

chroot /var/lib/docker/containers/2465790aa2c4*/root/

此处, 2465790aa2c4 是正在运行的容器的短ID(由 docker ps 显示),后跟一个星号。

答案 10 :(得分:4)

在我的情况下,sh之外的容器不支持任何外壳程序。所以,这就像一个魅力

docker exec -it <container-name> sh

答案 11 :(得分:4)

对于docker aufs驱动程序:

该脚本将找到容器根目录(在docker 1.7.1和1.10.3上测试)

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

答案 12 :(得分:3)

这个答案将帮助那些想要探索docker卷文件系统的人(比如我自己),即使容器没有运行。

列出正在运行的docker容器:

docker ps

=&GT;容器ID“4c721f1985bd”

查看本地物理计算机上的docker卷装入点(https://docs.docker.com/engine/tutorials/dockervolumes/):

docker inspect -f {{.Mounts}} 4c721f1985bd

=&GT; [{/ tmp / container-garren / tmp true rprivate}]

这告诉我本地物理机器目录/ tmp / container-garren被映射到/ tmp docker卷目的地。

了解本地物理机器目录(/ tmp / container-garren)意味着无论docker容器是否正在运行,我都可以探索文件系统。这对于帮助我弄清楚即使在容器未运行之后仍然存在一些残留数据至关重要。

答案 13 :(得分:3)

对于已经运行的容器,您可以执行以下操作:

dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])

cd /var/lib/docker/btrfs/subvolumes/$dockerId

你需要成为root才能进入该目录。如果你不是root用户,请在运行命令之前尝试'sudo su'。

编辑:在v1.3之后,请参阅Jiri的回答 - 它更好。

答案 14 :(得分:3)

另一个技巧是使用atomic工具执行以下操作:

CRTPF

Docker镜像将挂载到 / path / to / mnt ,供您检查。

答案 15 :(得分:3)

了解容器内部情况的首选方法是:

  1. 揭露-p 8000

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

    python -m SimpleHTTPServer
    

答案 16 :(得分:3)

在较新版本的Docker上,您可以运行docker exec [container_name]来运行容器中的shell

因此,要获取容器中所有文件的列表,只需运行docker exec [container_name] ls

答案 17 :(得分:2)

如果您使用的是Docker v19.03,请按照以下步骤操作。

# find ID of your running container:

  docker ps

# create image (snapshot) from container filesystem

  docker commit 12345678904b5 mysnapshot

# explore this filesystem 

  docker run -t -i mysnapshot /bin/sh

答案 18 :(得分:1)

您可以使用以下命令在容器内运行bash: $ docker run -it ubuntu /bin/bash

答案 19 :(得分:1)

现有答案中没有一个解决了容器退出(并且无法重新启动)和/或未安装任何外壳(例如,无外壳的外壳)的情况。只要您具有对Docker主机的root访问权限,此命令就可以工作。

要进行真正的手动检查,请先找出层ID:

docker inspect my-container | jq '.[0].GraphDriver.Data'

在输出中,您应该看到类似

"MergedDir": "/var/lib/docker/overlay2/03e8df748fab9526594cfdd0b6cf9f4b5160197e98fe580df0d36f19830308d9/merged"

导航到该文件夹​​(作为根用户)以找到容器文件系统的当前可见状态。

答案 20 :(得分:1)

仅适用于LINUX

我使用的最简单的方法是使用proc dir,即必须运行容器才能检查docker容器文件。

  1. 找出容器的进程ID(PID)并存储到某个变量中

      

    PID = $(码头工人检查-f'{{.State.Pid}}'您的容器名称-此处)

  2. 确保容器进程正在运行,并使用变量名进入容器文件夹

      

    cd / proc / $ PID / root

如果您不想仅通过使用此长命令就找到PID号就可以遍历目录

cd /proc/$(docker inspect -f '{{.State.Pid}}' your-container-name-here)/root

提示:

进入容器后,您所做的一切都会影响容器的实际过程,例如停止服务或更改端口号。

希望有帮助

注意:

此方法仅在容器仍在运行时才起作用,否则,如果容器已停止或删除,则该目录将不再存在

答案 21 :(得分:1)

在运行容器中运行命令的docker exec命令可以在多种情况下提供帮助。


Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Run a command in a running container

Options:
  -d, --detach               Detached mode: run command in the background
      --detach-keys string   Override the key sequence for detaching a
                             container
  -e, --env list             Set environment variables
  -i, --interactive          Keep STDIN open even if not attached
      --privileged           Give extended privileges to the command
  -t, --tty                  Allocate a pseudo-TTY
  -u, --user string          Username or UID (format:
                             [:])
  -w, --workdir string       Working directory inside the container

例如:

1)在bash中访问正在运行的容器文件系统:

docker exec -it containerId bash 

2)以root身份以运行bash的方式访问正在运行的容器文件系统,以具有必需的权限:

docker exec -it -u root containerId bash  

这对于以根用户身份在容器中进行一些处理特别有用。

3)用bash访问具有特定工作目录的正在运行的容器文件系统:

docker exec -it -w /var/lib containerId bash 

答案 22 :(得分:0)

这将启动图像的bash会话:

docker run --rm -it --entrypoint = / bin / bash

答案 23 :(得分:0)

您可以使用DIVE与TUI交互查看图像内容

https://github.com/wagoodman/dive

enter image description here

答案 24 :(得分:0)

如果您使用的是AUFS存储驱动程序,则可以使用我的docker-layer脚本查找任何容器的文件系统根目录(mnt)和readwrite图层:

# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt      : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f

编辑2018-03-28:
docker-layer已被docker-backup

取代

答案 25 :(得分:0)

我想这样做,但是由于代码中的某些错误,我无法执行到我的容器中,因为它已经停止并且无法再次启动。

对我有用的是简单地将整个容器的内容复制到新文件夹中,如下所示:

docker cp container_name:/app/ new_dummy_folder

然后,我能够像使用普通文件夹一样浏览此文件夹的内容。

答案 26 :(得分:0)

实际上我使用的所有容器都有 Python,所以我附加到容器中,

pip install jupyterlab
cd /
jupyter lab --allow-root

我 ^单击 Jupyter Lab 服务器提供的链接,在主机的浏览器中,我拥有完美的文件系统 GUI,可以打开各种文件(ipnb、py、md(预览中)...)

干杯
G.