上篇介绍了 alinode 自定义封装,但毕竟不是官网原配置,群里也有人吐槽过官网镜像太大。
所以这次分析官网镜像,看看到底为什么这么多大,顺便提取官网 Dockerfile。
官网镜像介绍
目前有 3
和 3-alpine
两种版本。3
镜像 732MB,为什么这么大?3-alpine
我提 issue 后正常了,仅仅 71.5MB。
其实无关大小,大家用镜像,无非图个省事,但没有 Dockerfile 用的人也很慌。
上一篇也提到了,官网有个一年多没更新过的 Dockerfile,其实也能用。
我们还是来着重分析下 3
版本,看看为什么这么大。
docker image 分析
逆向分析镜像有两种方法。
一种是 docker history
可以看到每一层的配置,但包括了从底层镜像开始的所有配置,所以会很杂乱。
另一种是 docker save
导出 tar 包,解压后,不仅可以得到每一层的配置,还能详细的看到每一层的文件增删情况。
这里我们讨论 docker history
方法,因为够用了。
docker history
1 | $ docker history --no-trunc registry.cn-hangzhou.aliyuncs.com/aliyun-node/alinode:3 > history.md |
这里加了 --no-trunc
参数,不截断数据,并且导出到 history.md
文件中。
ps: 由于
--no-trunc
的结果太长,不合适博客展示,所以这里贴了下截断后的数据。
1 | IMAGE CREATED CREATED BY SIZE COMMENT |
IMAGE
这列,全部丢失,只有最后一层有个 id。CREATED BY
是我们关注的主体,其他列都可以忽略。
当然你也可以看看 SIZE
太大的层可以去优化下命令。
在 CREATED BY
列中,全部是 /bin/sh -c
开头,但有的有 #(nop)
有的没有,这是为什么?
我也不知道,但仔细观察,其实可以发现没 #(nop)
是 RUN
指令的配置。
那么简单了,所有 /bin/sh -c #(nop)
删除,剩下的所有 /bin/sh -c
改成 RUN
就是我们要的 dockerfile 配置了。
再观察下发现好像最下面的是底层镜像配置,所以应该将结果倒序下才是我们要的 dockerfile。
这里写了个 bash 来辅助我们输出结果
1 | docker history \ |
保存为 history.sh
执行 sh history.sh
得到 dockerfile 文件,内容如下。
1 | ADD file:8d73a09e59fe50289a6d0c019302aefe2e00ac6411e82404389c0c83f50cf08a in / |
虽然还是有点乱,但至少得到了所有配置,接下来我们分析这些配置。
分析 history 提取最终 Dockerfile
这里先使用下我写的一个工具,重新得到格式化后的 dockerfile,方便我们分析,这个工具下一篇文章详细介绍。
1 | $ npx dockerfile-from-image registry.cn-hangzhou.aliyuncs.com/aliyun-node/alinode:3 > dockerfile |
PS: 不知道 npx 是什么或者 npx 命令无效的同学,请自行百度,这是神器,必须掌握。
得到如下 dockerfile 配置。
1 | FROM registry.cn-hangzhou.aliyuncs.com/aliyun-node/alinode:3 |
这样看就非常清晰了。
开头的 ADD file:xxx in /
和 CMD ["bash"]
明显就是基础镜像,接着往下看。
接下来各种 RUN
安装一大堆开发工具。。
直到 RUN groupadd --gid 1000 node \
才是我们熟悉的 node 环境相关的配置。
接着往下看,,一脸懵逼,怎么在安装官网 node ???不是说好的 alinode 么?
我们继续往下看,直到 ENV ALINODE_VERSION=3.12.0
才是我们 alinode 的配置。
下面不到10个指令,命令简洁明了,设置相关环境变量,然后从阿里云下载 alinode,解压到 /usr/local
目录。
然后是安装 agenthub 接着添加两个文件到 root目录 和 根目录。
其实是 default.config.js
复制到 /root
然后是 start-agenthub.sh
复制到 /
并作为 ENTRYPOINT
入口。
怎么提取这两个文件,下面详细说明,我们先整理 dockerfile。
从这里看,其实就是最后几条质量有用没其他都是些啥?
如果你对 node 镜像熟悉的话,其实不难发现,他是 node:8
的镜像。
1 | $ npx dockerfile-from-image node:8 > dockerfile |
得到
1 | FROM node:8 |
是不是一毛一样?
所以最终的 Dockerfile 是这样的。
1 | FROM node:8 |
瞬间明朗了,也知道为什么镜像这么大了。
node:8 Dockerfile 镜像依赖 buildpack-deps:jessie
。
从刚才的配置也看到了,几乎包含了所有开发编译时所需的各种工具。
那么还有个问题,default.config.js
, start-agenthub.sh
怎么提取?
1 | $ docker run --rm -it registry.cn-hangzhou.aliyuncs.com/aliyun-node/alinode:3 cat /start-agenthub.sh > start-agenthub.sh |
好了 Dockerfile
, default.config.js
, start-agenthub.sh
都得到了。
接着就可以 docker build -t alinode .
编译镜像了。
当然,你也可以为所欲为,各种魔改。
小结
我是一个喜欢刨根究底的人,这个事情其实上个月该做的,但各种琐事以及懒惰,拖到这个月才处理。
但结果是好的,把事情搞清楚了,以后遇到没有 Dockerfile 的镜像也可以分析出个大概。