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
Exploring Docker container's file system
提问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 exec
that 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/bash
to 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/
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-world
mentioned in the installation guide, or non-alpine
traefik
), this is probably the only possible method of exploring the filesystem.
如果您的容器已停止或没有外壳(例如hello-world
在安装指南中提到,或没有alpine
traefik
),这可能是探索文件系统的唯一可能方法。
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 ps
and if it's an apache or java
i 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/bash
or /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