请教大家一个 docker 镜像制作相关问题

2021-08-07 23:35:54 +08:00
 csfreshman

工作中最近用到 docker,今天看了一天网上的教程看网上的教程 https://www.runoob.com/docker/docker-dockerfile.html

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上执行会创建 3 层镜像。可简化为以下格式:
FROM centos
RUN yum install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

这里我试了这两种写法,docker 镜像的大小一样,这里制作 docker 镜像这两种写法有没有区别? centos:v3 是 3 个 run 生成的,v4 是第二种写法生成的。

[root Dockerfile]#docker image ls
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
centos            v4        ede9b36dd800   8 seconds ago   260MB
centos            v3        6df19efb1980   3 minutes ago   260MB
nginx             v3        3ca44131eb70   6 hours ago     133MB
2408 次点击
所在节点    程序员
12 条回复
muzuiget
2021-08-07 23:41:47 +08:00
你这个示例数据量不足到可以看出明显区别。

加多一个 RUN rm redis.tar.gz 就好了,后一种方法会少一个 redis.tar.gz 的大小。
singerll
2021-08-07 23:42:46 +08:00
你的操作太少了,而且几乎都是下载文件的操作
hefish
2021-08-07 23:48:28 +08:00
我觉着就上面的操作,没啥区别。不在乎那点。
jj256
2021-08-08 00:11:20 +08:00
dockerfile 里每次 run 生成的层只包含不同的部分,这点可以看下 docker 的 overlay 文件系统。所以我觉得只要执行的指令是一样的,分几层对镜像大小影响不大。
statumer
2021-08-08 01:08:36 +08:00
不要过早搞优化,精简镜像有很多方式,你真正在工作中遇见镜像产生瓶颈的情况再处理
在你这种情况,你观察一下命令行的输出会发现,实际上 docker 会自动移除一些中间层
Bromine0x23
2021-08-08 01:20:44 +08:00
如果命令执行结果只是单纯的文件新增,合不合并区别不大。但是如果存在文件修改和文件删除的话,合并后大小就能减少。
原因就是分层存储导致文件修改和文件删除的变化并不会影响到上层,从而整个镜像存储了无用的数据。
joetse
2021-08-08 03:40:10 +08:00
开发中分几层都无所谓, 能复用降低 build 的时间就行, 最终精简几乎都是用 from alpine copy --from=builder xx:yy
wd
2021-08-08 07:25:21 +08:00
膨胀主要是你在下一层无法清理上一层的文件,如果你没有这个需要,那应该无论顺序如何都一样。
ampedee
2021-08-08 08:41:17 +08:00
由于联合文件系统的存在,分再多层对镜像的体积影响也不大,合并指令的目的是为了清理无用的中间过程文件。
推荐花个几分钟看下这篇介绍容器镜像原理的文章:
https://www.waynerv.com/posts/learn-image-and-container-with-oci-spec/
ragnaroks
2021-08-08 09:44:49 +08:00
你这本来就没区别,都是增加文件的操作,你起码最后要有个移除文件的操作
ch2
2021-08-08 09:45:47 +08:00
镜像大小无所谓的,大不了删了就是
jim9606
2021-08-08 15:09:29 +08:00
你这个例子只有新增文件,大小区别基本没有,只有包含删除文件的操作才能体现区别。
如果你这里的增加到下载、解压、编译、安装步骤,那么后面把源码和中间产物删掉才能体现区别。
我个人并不喜欢将这几个步骤合并,因为 build 镜像时没法保留中间结果,导致每次出错重试都得重下源码。我倾向于用多阶段构建( Dockerfile 包含多个 FROM )

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/794338

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX