Linux 探索 Docker 容器的文件系统

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20813486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:42:54  来源:igfitidea点击:

Exploring Docker container's file system

linuxdockerfilesystems

提问by user2668128

I've noticed with docker that I need to understand what's happening inside a container or what files exist in there. One example is downloading images from the docker index - you don't have a clue what the image contains so it's impossible to start the application.

我注意到 docker 我需要了解容器内发生的事情或那里存在哪些文件。一个例子是从 docker index 下载图像——你不知道图像包含什么,所以不可能启动应用程序。

What would be ideal is to be able to ssh into them or equivalent. Is there a tool to do this, or is my conceptualisation of docker wrong in thinking I should be able to do this.

理想的情况是能够通过 ssh 进入它们或等效物。是否有工具可以做到这一点,或者我认为我应该能够做到这一点对 docker 的概念化是错误的。

采纳答案by Jiri

UPDATE
Easiest method: Using docker exec

更新
最简单的方法:使用 docker exec

Docker version 1.3 or newer supports the command execthat behave similar to nsenter. This command can run new process in already running container (container must have PID 1 process running already). You can run /bin/bashto explore container state:

Docker 1.3 或更高版本支持exec行为类似于nsenter. 此命令可以在已经运行的容器中运行新进程(容器必须已经运行了 PID 1 进程)。您可以运行/bin/bash以探索容器状态:

docker exec -t -i mycontainer /bin/bash

see Docker command line documentation

请参阅Docker 命令行文档

Alternate method 1
Snapshotting

替代方法 1
快照

You can evaluate container filesystem this way:

您可以通过以下方式评估容器文件系统:

# 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

This way, you can evaluate filesystem of the running container in the precise time moment. Container is still running, no future changes are included.

通过这种方式,您可以在精确的时刻评估正在运行的容器的文件系统。容器仍在运行,不包括未来的更改。

You can later delete snapshot using (filesystem of the running container is not affected!):

您可以稍后使用(正在运行的容器的文件系统不受影响!)删除快照:

docker rmi mysnapshot

Alternate method 2
ssh

替代方法 2
ssh

If you need continuous access, you can install sshd to your container and run the sshd daemon:

如果您需要持续访问,您可以将 sshd 安装到您的容器并运行 sshd 守护进程:

 docker run -d -p 22 mysnapshot /usr/sbin/sshd -D

 # you need to find out which port to connect:
 docker ps

This way, you can run your app using ssh (connect and execute what you want).

这样,您就可以使用 ssh 运行您的应用程序(连接并执行您想要的操作)。

UPDATE: Alternate method 3
nsenter

更新:替代方法 3
nsenter

Use nsenter, see https://web.archive.org/web/20160305150559/http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/

使用nsenter,见https://web.archive.org/web/20160305150559/http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/

The short version is: with nsenter, you can get a shell into an existing container, even if that container doesn't run SSH or any kind of special-purpose daemon

简短版本是:使用 nsenter,您可以将 shell 放入现有容器中,即使该容器不运行 SSH 或任何类型的专用守护程序

回答by Rovanion

The file system of the container is in the data folder of docker, normally in /var/lib/docker. In order to start and inspect a running containers file system do the following:

容器的文件系统在docker的data文件夹中,一般在/var/lib/docker中。为了启动和检查正在运行的容器文件系统,请执行以下操作:

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

And now the current working directory is the root of the container.

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

回答by AlonL

For an already running container, you can do:

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

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

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

You need to be root in order to cd into that dir. If you are not root, try 'sudo su' before running the command.

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

Edit: Following v1.3, see Jiri's answer - it is better.

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

回答by dashohoxha

For me, this one works well (thanks to the last comments for pointing out the directory /var/lib/docker/):

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

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

Here, 2465790aa2c4is the short ID of the running container (as displayed by docker ps), followed by a star.

这里,2465790aa2c4是正在运行的容器的短 ID(如docker ps 所示),后跟一个星号。

回答by piercebot

On Ubuntu 14.04running Docker 1.3.1, I found the container root filesystem on the host machine in the following directory:

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

/var/lib/docker/devicemapper/mnt/<container id>/rootfs/

Full Docker version information:

完整的 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

回答by Ilya Murav'jov

In case your container is stopped or doesn't have a shell (e.g. hello-worldmentioned in the installation guide, or non-alpinetraefik), this is probably the only possible method of exploring the filesystem.

如果您的容器已停止或没有外壳(例如hello-world安装指南中提到,或没有alpinetraefik),这可能是探索文件系统的唯一可能方法。

You may archive your container's filesystem into tar file:

您可以将容器的文件系统归档到 tar 文件中:

docker export adoring_kowalevski > contents.tar

Or list the files:

或者列出文件:

docker export adoring_kowalevski | tar t

Do note, that depending on the image, it might take some time and disk space.

请注意,根据图像,它可能需要一些时间和磁盘空间。

回答by telamon

I use another dirty trick that is aufs/devicemapper agnostic.

我使用了另一个与 aufs/devicemapper 无关的肮脏技巧。

I look at the command that the container is running e.g. docker psand if it's an apache or javai just do the following:

我查看容器正在运行的命令,docker ps如果它是一个 apache 或者java我只是执行以下操作:

sudo -s
cd /proc/$(pgrep java)/root/

and voilá you're inside the container.

瞧,你在容器内。

Basically you can as root cd into /proc/<PID>/root/folder as long as that process is run by the container. Beware symlinks will not make sense wile using that mode.

基本上/proc/<PID>/root/,只要该进程由容器运行,您就可以以 root cd 进入文件夹。当心符号链接在使用该模式时没有意义。

回答by Florent

The most voted answer is good except if your container isn't an actual Linux system.

投票最多的答案是好的,除非您的容器不是实际的 Linux 系统。

Many containers (especially the go based ones) don't have any standard binary (no /bin/bashor /bin/sh). In that case, you will need to access the actual containers file directly:

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

Works like a charm:

奇迹般有效:

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

Note: You need to run it as root.

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

回答by xrh

On newer versions of Docker you can run docker exec [container_name]which runs a shell inside your container

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

So to get a list of all the files in a container just run docker exec [container_name] ls

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

回答by qxo

For docker aufs driver:

对于 docker aufs 驱动程序:

The script will find the container root dir(Test on docker 1.7.1 and 1.10.3 )

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

if [ -z "" ] ; then
 echo 'docker-find-root $container_id_or_name '
 exit 1
fi
CID=$(docker inspect   --format {{.Id}} )
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