更新时间:2026-05-13
点击次数: 我们在使用 CI/CD 的时候,如果用于构建或运行的镜像较大,会直接影响拉取速度,进而影响构建与部署的时间。本文会简单介绍一下 Docker 的镜像大小是什么决定的,然后针对以下几种常见的镜像使用场景,介绍如何减少镜像的空间:
Docker 使用存储驱动程序(storage drivers)来存储镜像的层和容器的可写层。存储驱动程序针对空间效率进行了优化,但写入速度低于本机文件系统性能(取决于存储驱动程序)。
类似于数据库存储、本地日志服务的写入密集型应用程序应当使用 Docker Volumn,不然会受存储驱动性能开销的影响,尤其在只读层中存在预先存在的数据的情况下。(关于卷更广为人知的是:用于在容器生命周期之外保留的数据、容器之间共享的数据)
Dockerfile 中的FROM和RUN的行都会生成层,无论是生成文件或删除文件,都会产生新的层。这些层是只读的,随着 Dockerfile 的增加,后边的层依赖前面的层,堆叠在一起。
镜像的大小,就是每层累积起来的大小,而镜像的每一层都是只读层。最后的CMD表示在容器里运行的指令,是不会在镜像中产生层的。
容器和镜像之间的主要区别在于顶层可写层。当创建一个新容器时,会在镜像的层基础上,增加一个可写层(通常被称为“容器层”)。对正在运行的容器所做的所有更改,例如写入新文件、修改现有文件和删除文件,都将写入这个薄的可写容器层(thin R/W layer)。当容器被删除时,可写层也被删除。
因为每个容器都有自己的可写容器层,所以多个容器可以共享对同一底层镜像的访问,但有自己的数据状态。

写时复制 (CoW) 是一种高效的共享/复制文件策略。如果一个文件或目录存在于镜像中的较低层,而另一更高层(包括可写层)需要对其进行读取访问时:文件被从低层复制到高层并进行修改。这最大限度地减少了 I/O 和每个后续层的大小。
接下来,以一个实际的 Dockerfile 进行构建和运行,来形象地展示镜像、容器、层之间的关系。

根据前面的介绍,每次RUN都会产生一个层,而这些层是累积的。因此,如果我们自己写 Dockerfile 的时候,就要每一个RUN都要清理自己产生的后边不需要的中间文件。这些中间文件包括:
我们先构建一个【比较大的+没有Dockerfile+有无用数据在层里累积】的镜像,然后再拿这个镜像,做优化的练习。
之前 dev-cloud 提供的容器服务,并不是像现在一样提供的容器集群,而是提供拉起的单个 Docker 容器。使用卷的方式,存储需要持久化的数据。同时,还提供将当前容器的状态,打成镜像并上传的功能。
我们在单机上也能通过拉起基础镜像,进行操作,然后再将结果打成新的镜像,跟上边的流程原理应该是一样的。接下来介绍下如何操作:
上边的操作得到了一个两层的镜像,你可以直接通过docker pull拉取,也可以直接通过docker run运行:
如前边解释的【进入容器直接删掉文件,然后对该容器做镜像】只能增加一层,而不会减小镜像大小:
裁剪现有镜像需要使用docker export+docker import将容器的状态,导出成一层然后导入,这样删除起作用了。实际是通过丢弃层累积的信息来实现的。具体的:
电子邮箱: facai@126.com
热线电话: 0755-89800918
公司地址: 深圳市南山区粤海街道高新区社区深圳湾创新科技中心2栋A座22层
Copyright © 2012-202X 球速体育公司 版权所有 Powered by EyouCms
备案号:粤ICP备05004158号-1
