Docker 的一些反编译操作
dfimage(从镜像中提取 Dockerfile)
简介
dfimage 项目 —— 从 Docker 镜像反推 Dockerfile 文件。
与 docker history
命令的工作方式类似,Python 脚本能够利用 Docker 在每个镜像层旁存储的元数据重新创建用于生成镜像的大致 Dockerfile 脚本。
用法
# 下载镜像
docker pull ghcr.io/laniksj/dfimage:latest
docker run -v /var/run/docker.sock:/var/run/docker.sock dfimage ruby:latest
ruby:latest
参数是镜像的名称和标签。
由于该脚本与 Docker API
交互,以查询各种元数据,它需要访问 Docker API
套接字。
注意:该命令只对存在于你本地镜像库中的镜像起作用(即 docker images
指令能看到的镜像)。如果你想为一个不存在于本地仓库的镜像逆向一个 Dockerfile
文件,你需要先 docker pull
它。
实战
下面是一个 ruby
镜像逆向 Dockerfile
文件的例子。
$ docker pull ghcr.io/laniksj/dfimage
Using default tag: latest
latest: Pulling from dfimage
$ alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/laniksj/dfimage"
$ dfimage ruby:latest
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
alias:设置命令别名。格式 ->
alias 别名='原命令 -选项/参数'
alias
命令只作用于当次登入的操作。如果想每次登入都能使用这些命令的别名,则可以把相应的alias
命令存放在~/.bashrc
文件中。cd ~ vim .bashrc # 在 User specific aliases and functions 这行下面加入命令 alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/laniksj/dfimage" # 执行 :wq 命令保存文件 source .bashrc
从容器中提取 docker run 命令
方法一:rekcod
简介
rekcod —— 从现有容器逆向工程 docker run 命令(通过 docker inspect)。
rekcod
可以将以下任何内容转换为docker run
命令:
- 容器 ID/名称(
rekcod
将调用docker inspect
) docker inspect
包含输出的文件的路径- 原始 JSON(
docker inspect
直接传递输出)
用法
# 下载镜像
docker pull nexdrew/rekcod
# 设置临时命令别名,永久设置方法请参考上面的 dfimage
alias rekcod="docker run --rm -i -v /var/run/docker.sock:/var/run/docker.sock nexdrew/rekcod"
# 生成容器启动命令
rekcod <容器>
实战
# 容器作为参数
$ rekcod container-one 6653931e39f2 happy_torvalds
docker run --name container-one ...
docker run --name stinky_jones ...
docker run --name happy_torvalds ...
# 容器中的管道
$ docker ps -aq | rekcod
docker run --name container-one ...
docker run --name stinky_jones ...
docker run --name happy_torvalds ...
方法二:runlike
简介
runlike** —— 给定一个现有的 docker 容器,打印运行它所需的命令行。
你给它一个 docker 容器,它就会输出运行该容器所需的大致命令,以及那些讨厌的选项(如:端口、链接、卷...)。对于那些通常通过工具批量部署 docker 容器,然后发现自己需要手动重新运行一些容器的人来说,这简直是个好软件。
用法
# 下载镜像
docker pull assaflavie/runlike
# 设置临时命令别名,永久设置方法请参考上面的 dfimage
alias runlike="docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike"
# 生成容器启动命令
runlike <YOUR-CONTAINER>
实战
这会打印出您需要运行什么才能获得类似的容器。您可以 $(runlike container-name)
简单地一步执行其输出。
-p
将命令行分解为漂亮、漂亮的行。例如:
$ runlike -p redis
docker run \
--name=redis \
-e "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
-e "REDIS_VERSION=2.8.9" \
-e "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-2.8.9.tar.gz" \
-e "REDIS_DOWNLOAD_SHA1=003ccdc175816e0a751919cf508f1318e54aac1e" \
-p 0.0.0.0:6379:6379/tcp \
--detach=true \
myrepo/redis:7860c450dbee9878d5215595b390b9be8fa94c89 \
redis-server --slaveof 172.31.17.84 6379
将其输出 docker inspect
也提供给它:
docker inspect <container-name> | runlike --stdin
--no-name
将从输出中省略容器名称(以避免冲突)。
生成结果对比