探索 Docker 容器的文件系统

我注意到 docker 我需要了解容器内发生了什么或其中存在哪些文件。一个例子是从 docker index 下载图像——你不知道图像包含什么,因此无法启动应用程序。

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

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

这里有几种不同的方法…

A)使用 docker exec(最简单)

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

docker exec -t -i mycontainer /bin/bash 

见Docker command line documentation

B) 使用快照

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

# 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 

C) 使用 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 运行您的应用程序(连接并执行您想要的)。

D) 使用 nsenter

使用 nsenter,见 Why you don’t need to run SSHd in your Docker containers

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

但请注意,如果您需要访问文件,请使用“docker cp”命令用法: docker cp CONTAINER:PATH HOSTPATH 将文件/文件夹从容器文件系统复制到主机路径。路径是相对于文件系统的根目录的。 #> docker cp 7bb0e258aefe:/etc/debian_version 。 #> docker cp blue_frog:/etc/hosts 。

选项 4 非常重要,应将其移至顶部并重命名为 Option 1。

@JanusTroelsen 如果没有外壳,您可以安装它 - 例如在 alpine linux 的 dockerfile 中(确实没有外壳):RUN apk update && apk add bash(大小:~4MB)

根据我自己的经验,Docker exec 的限制是该命令必须添加到正在运行的容器上或作为一种入口点。因此,停止的容器超出了此方法的范围。

要使用 Window 的 linux shell,请使用 docker exec -t -i mycontainer /bin/sh

huntsbot.com – 高效赚钱,自由工作

更新:探索!

这个命令应该让你探索一个正在运行的 docker 容器:

docker exec -it name-of-container bash 

docker-compose 中的等效项是:

docker-compose exec web bash 

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

一旦你在里面做:

ls -lsa 

或任何其他 bash 命令,例如:

cd .. 

这个命令应该让你探索一个 docker 镜像:

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

一旦进入内部做:

ls -lsa 

或任何其他 bash 命令,例如:

cd .. 

-it 代表交互式…和 tty。

此命令应允许您检查正在运行的 docker 容器或映像:

docker inspect name-of-container-or-image

您可能想要这样做并找出其中是否有任何 bash 或 sh。在 json 返回中查找入口点或 cmd。

注意:此答案依赖于存在的常用工具,但如果没有 bash shell 或 ls 等常用工具,如果您有权访问 { 3}:高山的例子:

RUN apk add --no-cache bash 

否则,如果您无权访问 Dockerfile,则只需将文件从新创建的容器中复制出来,然后通过执行以下操作查看它们:

docker create # returns container ID the container is never started. docker cp : docker rm cd && ls -lsah 

见docker exec documentation

见docker-compose exec documentation

见docker inspect documentation

见docker create documentation

这非常有用,谢谢!我需要将包含在 docker 图像文件结构中的文件拖放到应用程序中,但除非它以 GUI 格式打开,否则这是不可能的。知道我该如何解决这个问题吗?

很明显,这只适用于安装了 bash 的容器。

对于想在 Windows Container/Powershell 上执行此操作的任何人,命令是 docker exec -ti powershell (source)

@ssell 我的容器/图像由于某种原因没有 powershell,所以 docker exec -ti cmd 工作。对于像我这样的其他新手,请确保使用来自 docker ps 的容器实例名称(类似于 070494393ca5),而不是您为其分配的可读名称。

关于图像中的 powershell github.com/aspnet/aspnet-docker/issues/362 - 如果您只需要在 Windows 图像上卷曲:blogs.technet.microsoft.com/virtualization/2017/12/19/…

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

如果您的容器已停止或没有外壳(例如 installation guide 中提到的 hello-world 或非 alpine traefik),这可能是探索文件系统的唯一可能方法。

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

docker export adoring_kowalevski > contents.tar 

或列出文件:

docker export adoring_kowalevski | tar t 

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

我只是想列出一个没有安装标准 UNIX 工具的容器的内容。上面 export 示例的一个变体恰如其分:docker export adoring_kowalevski | tar tf -

对粗心的人的警告:这可能会导出大量数据(> GB)并需要很长时间。

@berto 并不是说这是一件大事,但是您不需要 f - 在命令末尾, tar 默认情况下从标准输入读取。只需 docker export adoring_kowalevski | tar t 即可。

越简单越好;太棒了,谢谢你的提示! 🙌🏽

@ShaunBouckaert tar f 的默认值取决于一个人的配置。一部分是 TAPE 环境变量。其他的则作为构建的一部分进行控制。最终结果是,永远不要假设它读取 stdin 或写入 stdout,但始终明确说明。

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

最受好评的答案是在容器实际启动时为我工作,但是当它无法运行并且您例如想要从容器中复制文件时,这已经救了我:

docker cp : 

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

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

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

为什么这没有更多的+1!绝对是最好的方法

这比通过 tar 导出还要简单。我必须使用 -L 通过符号链接访问文件。无需运行容器!

这应该是公认的答案!特别是如果您想在 docker 容器由于某种原因(“调试”)无法运行时探索文件系统。这种方式简单易行。

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

容器创建之前:

如果您要探索安装在容器内的图像的结构,您可以这样做

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

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

容器创建后:

为此,上面已经有很多答案。我首选的方法是-

docker exec -t -i container /bin/bash 

参见sreeninet.wordpress.com/2016/06/11/…。

这里应该提到的是,只有在与映像具有相同架构的机器上运行 bash 才能在容器内运行。如果您在 PC 上试图窥探 raspberry pi 的图像文件系统,那么 bash 技巧将不起作用。

@MaximKulkin 真的吗?如果容器是 Linux,那么主机是什么并不重要,如果 bash 可用。也许您正在考虑 Windows 容器?

在极少数情况下,我只能在容器中未加载 bash 时输入 sh 提示。

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

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

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

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

不过,这不包括任何已安装的卷。

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

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

https://github.com/wagoodman/dive

https://i.stack.imgur.com/OLFEC.png

潜水真的是完美的工具!

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

尝试使用

docker exec -it /bin/bash 

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

docker exec -it sh 

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

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

/var/lib/docker/devicemapper/mnt 

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

像魅力一样工作: name= dockerId=$(docker inspect -f {{.Id}} $name) /var/lib/docker/devicemapper/mnt/$dockerId/rootfs/

不幸的是,在 Ubuntu 16.10 和 docker 1.12.1 中,情况不再如此(没有devicemapper目录)。该文件存在于 /var/lib/docker/overlay//... 下。我不确定在那里访问文件的便携性/安全性

从 1.10 开始,Docker 引入了一种新的内容可寻址存储模型,它不使用随机生成的 UUID,就像以前用于层和容器标识符一样。在新模型中,这被层 id 的安全内容散列所取代。所以这种方法将不再有效。

这不是可移植的,很大程度上取决于 storage driver 的选择。例如,不确定该解决方案是否适用于 direct-lvm。

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

在我的情况下,除了 sh 之外,容器中不支持任何 shell。所以,这就像一个魅力

docker exec -it sh 

谢谢,考虑到OP询问如何通过SSH进入容器,我觉得这应该更高。

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求

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

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

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

瞧,你在容器里面。

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

此处有关此方法的其他信息:superuser.com/a/1288058/195840

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

原文链接:https://blog.csdn.net/kalman2019/article/details/128732235?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168994567316782427435997%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=168994567316782427435997&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-26-128732235-null-null.268%5Ev1%5Ekoosearch&utm_term=docker%E3%80%81wordpress%E3%80%81wordpress%E5%BB%BA%E7%AB%99%E3%80%81wordpress%E4%B8%BB%E9%A2%98%E3%80%81%E5%AE%B9%E5%99%A8%E9%95%9C%E5%83%8F%E3%80%81

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享