如何基于Docker镜像逆向生成Dockerfile

引言你是否曾经遇到过一个想要使用的 Docker 镜像,但却无法修改以适应你的特定需求?或者你可能发现了一个喜欢的 Docker 镜像 , 但想要了解它是如何构建的?在这两种情况下 , 将 Docker 镜像逆向生成一个 Dockerfile 可以使用一些工具来实现 。
将 Docker 镜像转换为 Dockerfile 意味着获取现有的 Docker 镜像 , 并使用它来创建一个你可以修改和控制的 Dockerfile 。
这个过程让你能够理解 Docker 镜像的内部运作方式,进行修改 , 更新镜像以在不同平台上运行,或者根据特定需求对其进行优化 。
在这篇博客文章中,我们将通过使用一些开源工具,带领您逐步解读 Docker 镜像并转换为 Dockerfile 的过程 。
使用Dedockify工具实现

如何基于Docker镜像逆向生成Dockerfile

文章插图
图片
Docker 镜像就像黑匣子,包含了在镜像构建过程中执行的一系列指令层 。
现在有了 Dedockify,一个使用 Python/ target=_blank class=infotextkey>Python 脚本的工具,可以帮助重建创建镜像所使用的 Dockerfile 的近似版本 。
Dedockify 的工作原理是利用存储在每个镜像层旁边的元数据 。它通过沿着层级树向后遍历,收集与每个层相关联的命令 。
这个过程使它能够重建在镜像构建过程中执行的命令序列 。
然而,有一个问题:如果使用了 COPY 或 ADD 指令,Dedockify 生成的输出不会完全匹配原始的 Dockerfile 。这是因为 Dedockify 无法访问在执行原始的 docker build 命令时存在的构建上下文 。
要使用 Dedockify,可以将其作为一个 Docker 容器运行:
docker run -v /var/run/docker.sock:/var/run/docker.sock dedockify <imageID>参数 <imageID> 是镜像 ID(可以是缩短形式或完整的镜像 ID) 。
该脚本通过与 Docker API 交互来查询各个镜像层的元数据,因此需要访问 Docker API 套接字 。上面显示的 -v 标志使得在运行脚本的容器内部可以使用 Docker 套接字 。
工作原理是什么?
当从 Dockerfile 构建镜像时,Dockerfile 中的每个指令都会生成一个新的层 。您可以使用 docker images 命令和(现在已弃用的)--tree 标志来查看所有的镜像层 。
$ docker images --treeWarning: '--tree' is deprecated, it will be removed soon. See usage.└─511136ea3c5a Virtual Size: 0 B Tags: scratch:latest└─1e8abad02296 Virtual Size: 121.8 MB└─f106b5d7508a Virtual Size: 121.8 MB└─0ae4b97648db Virtual Size: 690.2 MB└─a2df34bb17f4 Virtual Size: 808.3 MB Tags: buildpack-deps:latest└─86258af941f7 Virtual Size: 808.6 MB└─1dc22fbdefef Virtual Size: 846.7 MB└─00227c86ea87 Virtual Size: 863.7 MB└─564e6df9f1e2 Virtual Size: 1.009 GB└─55a2d383d743 Virtual Size: 1.009 GB└─367e535883e4 Virtual Size: 1.154 GB└─a47bb557ed2a Virtual Size: 1.154 GB└─0d4496202bc0 Virtual Size: 1.157 GB└─5db44b586412 Virtual Size: 1.446 GB└─bef6f00c8d6d Virtual Size: 1.451 GB└─5f9bee597a47 Virtual Size: 1.451 GB└─bb98b84e0658 Virtual Size: 1.452 GB└─6556c531b6c1 Virtual Size: 1.552 GB└─569e14fd7575 Virtual Size: 1.552 GB└─fc3a205ba3de Virtual Size: 1.555 GB└─5fd3b530d269 Virtual Size: 1.555 GB└─6bdb3289ca8b Virtual Size: 1.555 GB└─011aa33ba92b Virtual Size: 1.555 GB Tags: ruby:2, ruby:2.1, ruby:2.1.1, ruby:latest这些层中的每一个都是在 Dockerfile 中执行指令的结果 。事实上,如果您对这些层中的任何一个执行 docker inspect,您可以看到用于生成该层的指令 。
$ docker inspect 011aa33ba92b[{. . ."ContAInerConfig": {"Cmd": ["/bin/sh","-c","#(nop) ONBUILD RUN [ ! -e Gemfile ] || bundle install --system"],. . .}]Docker 示例:
以下是一个示例 , 展示了如何拉取官方的 Docker Ruby 镜像并生成该镜像的 Dockerfile 。
$ docker pull mrhavens/dedockifyUsing default tag: latestlatest: Pulling from dedockify$ alias dedockify="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm mrhavens/dedockify"$ dedockify <imageID>FROM buildpack-deps:latestRUN useradd -g users userRUN apt-get update && apt-get install -y bison procpsRUN apt-get update && apt-get install -y rubyADD dir:03090a5fdc5feb8b4f1d6a69214c37b5f6d653f5185cddb6bf7fd71e6ded561c in /usr/src/rubyWORKDIR /usr/src/rubyRUN chown -R user:users .USER userRUN autoconf && ./configure --disable-install-docRUN make -j"$(nproc)"RUN make checkUSER rootRUN apt-get purge -y rubyRUN make installRUN echo 'gem: --no-rdoc --no-ri' >> /.gemrcRUN gem install bundlerONBUILD ADD . /usr/src/AppONBUILD WORKDIR /usr/src/appONBUILD RUN [ ! -e Gemfile ] || bundle install --system


推荐阅读