Dedockify
是一个用于逆向Docker 镜像并生成相应 Dockerfile 的工具。
它的主要功能是通过解析 Docker 镜像的metadata(也就是history),重建出用于生成该镜像的 Dockerfile。
开源仓库地址: https://github.com/mrhavens/Dedockify
主要功能
- 逆向工程 Docker 镜像:Dedockify 能够从 Docker 镜像中提取信息,并生成一个近似的 Dockerfile。这对于需要了解镜像构建过程或修改镜像的用户非常有用。
- 使用 Docker API:Dedockify 利用 Python Docker API 与 Docker 交互,获取镜像的各层信息,并将这些信息重新格式化为 Dockerfile。
- 支持本地镜像:该工具只能对本地存在的 Docker 镜像进行操作。如果镜像不在本地仓库中,需要先使用
docker pull
命令将其拉取下来。
使用方法
基本用法
-
拉取 Dedockify 镜像:
docker pull mrhavens/dedockify
-
创建别名:
alias dedockify="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm mrhavens/dedockify"
-
生成 Dockerfile:
dedockify <imageID>
其中
<imageID>
是目标 Docker 镜像的 ID,可以是截断形式或完整形式。
⚠️注意:。下面笔者给出一个fix:
首先需要安装最新的docker python sdk:
pip install docker
然后修改dedockify.py
为如下:
#!/usr/bin/python3
from sys import argv
import docker
import docker.errors
class ImageNotFound(Exception):
pass
class MainObj:
def __init__(self):
super(MainObj, self).__init__()
self.commands = []
self.cli = docker.client.from_env()
self._get_image(argv[-1])
self.hist = self.img.history()
self._parse_history()
self.commands.reverse()
self._print_commands()
def _print_commands(self):
for i in self.commands:
print(i)
def _get_image(self, img_hash):
try:
img = self.cli.images.get(img_hash)
self.img = img
except docker.errors.ImageNotFound:
raise ImageNotFound("Image {} not found".format(img_hash))
def _insert_step(self, step):
if "#(nop)" in step:
to_add = step.split("#(nop) ")[1]
else:
to_add = ("RUN {}".format(step))
to_add = to_add.replace("&&", "\\\n &&")
self.commands.append(to_add.strip(' '))
def _parse_history(self, rec=False):
first_tag = False
actual_tag = False
for i in self.hist:
if i['Tags']:
actual_tag = i['Tags'][0]
if first_tag and not rec:
break
first_tag = True
self._insert_step(i['CreatedBy'])
if not rec:
self.commands.append("FROM {}".format(actual_tag))
__main__ = MainObj()
如果docker build过程中遇到速度很慢的问题,可以通过修改apk源和pip源解决,下面是一个修改后的例子:
FROM alpine:3.11.3
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
RUN apk --no-cache update && apk add --no-cache python3 wget \
&& wget -q --no-check-certificate https://bootstrap.pypa.io/get-pip.py \
&& apk del wget && python3 get-pip.py && rm -f get-pip.py \
&& pip install -U docker pip -i https://pypi.tuna.tsinghua.edu.cn/simple && yes | pip uninstall pip
RUN mkdir /app
COPY entrypoint.sh /.
COPY dedockify.py /app/.
ENTRYPOINT ["/entrypoint.sh"]
修改后的完整代码可以从笔者的fork中获取:https://github.com/merthmagic/Dedockify
示例
以下是一个使用 Dedockify 生成 Dockerfile 的示例:
## ⚠️ 如果不能工作,请用上面的更新后代码自行打包docker image
$ docker pull mrhavens/dedockify
$ alias dedockify="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm mrhavens/dedockify"
$ dedockify <imageID>
生成的 Dockerfile 可能如下所示:
FROM buildpack-deps:latest
RUN useradd -g users user
RUN apt-get update && apt-get install -y bison procps
RUN apt-get update && apt-get install -y ruby
ADD dir:03090a5fdc5feb8b4f1d6a69214c37b5f6d653f5185cddb6bf7fd71e6ded561c in /usr/src/ruby
WORKDIR /usr/src/ruby
RUN chown -R user:users .
USER user
RUN autoconf && ./configure --disable-install-doc
RUN make -j"$(nproc)"
RUN make check
USER root
RUN apt-get purge -y ruby
RUN make install
RUN echo 'gem: --no-rdoc --no-ri' >> /.gemrc
RUN gem install bundler
ONBUILD ADD . /usr/src/app
ONBUILD WORKDIR /usr/src/app
ONBUILD RUN [ ! -e Gemfile ] || bundle install --system
限制
Dedockify 目前有一些限制,例如它无法处理所有类型的指令,特别是涉及复杂文件操作的指令。此外,未来的改进方向包括自动恢复容器中的文件并将其存储到本地,以及更好地推断基础镜像等。
但总的来说,Dedockify 是一个强大的工具,通过Dedockify再配合一些后续处理,能够帮助开发者和运维人员更好地理解和管理 Docker 镜像。