Docker镜像优化

一 Docker镜像优化层面

  • 空间优化,也就是优化 Docker 镜像体积(也称呼为“镜像瘦身”)
  • 优化 Docker 镜像构建速度,是优化构建的时间

二 Docker镜像优化方式

    1. 选择最精简的基础镜像
    1. 合理规划镜像的层数
    1. 清理镜像构建的中间产物
    1. 优化网络需求
    1. 构建缓存
    1. 使用多阶段构建镜像
    1. 编写 .dockerignore 文件

上述中: 空间优化(1、3、6)时间优化(4、5、7)

三 时间优化

​ 时间层面的优化方式有网络优化、构建缓存、编写 .dockerignore 文件 3 种方式;

  1. 网络优化

    ​ 优化网络主要是为了让镜像下载或者依赖的安装、代码下载在网络通道上更加通畅。常用的优化方式例如:调整构建机器网络质量、配置就近的加速仓库地址等等。

  2. 构建缓存

    • 本地缓存

      ​ Docker 构建时下载基础镜像文件会进行缓存,所以构建缓存优化时,为了减少镜像的传输下载时间,建议使用固定的机器来专门进行镜像的构建。

    • 镜像分层缓存

      ​ Docker 的一大特色就是镜像的存储分层,在 dockerfile 中的每一个指令会对应到镜像的每一层,并且默认启用缓存,所以构建时每一层是否会缓存取决于三个关键因素:

      • 镜像父层没有发生变化

      • 构建指令不变

      • 添加文件校验和一致

      只要一个构建指令满足这三个条件,这一层镜像构建就不会再执行,而是直接利用之前构建的结果。

  3. 编写 .dockerignore 文件

    ​ 编写 .dockerignore 文件用于过滤构建过程中不必要的文件,或者创建单独的目录(如 .git 文件夹,markdown 文档等),从而减小目标镜像大小,加快构造速度。

四 空间优化

  1. 选择最精简的基础镜像

    ​ Docker 的仓库中存在同一个基础镜像的多个版本,为了优化 Docker 体积,我们通常会建议使用 Alpine 类型的版本,因为 Alpine 镜像和类似的其他镜像都经过了优化,其中仅包含最少、必须的软件包,所以它能够节省很多体积。

    ​ Alpine 类型的镜像被很多开发技术人员优先推荐。但是Alpine镜像也存在很多问题:

    • 使用 Alpine 镜像程序容易报错

      因为 Alpine 为了追求精简,很多依赖库都没有,需要一些依赖动态链接库的程序运行时就容易报错,比如 Go 的 cgo 调用。

    • 域名解析行为跟 glibc 有差异

      Alpine 镜像的底层库是 musl libc,域名解析行为跟标准 glibc 有差异,需要特殊作一些修复配置,并且有部分选项在 resolv.conf 中配置不支持。

    • 运行 bash 脚本不兼容

      因为没有内置 bash,所以运行 bash 的 shell 脚本会不兼容。

    ​ 除此之外,使用 Alpine 镜像还会导致时区不一致、无法通过 lxcfs 提升容器资源可见性等问题。所以,你在真正使用之前需要评估好 Alpine 的弊端和风险,如果一定需要使用 Alpine 镜像,最好的方式是先使用 Alpine 镜像做基础镜像,在项目直接使用 Alpine 镜像之前进行一次初始化,然后再用初始化后的版本作为通用的基础镜像。

  1. 合理规划镜像的层数

    ​ 除了精简的基础镜像,你还可以在编写 dockerfile 时,根据实际情况去合并一些指令,尽量减少镜像层级,以此来优化体积。

    ​ 在 dockerfile 中每执行一条指令,就会提交一次修改,这次修改会保存成一个只读层挂载到联合文件系统,上面层的文件如果和下面层有冲突或不同,会覆盖隐藏底层的文件,所以每增加一层,镜像大小就会增加,但是在 Docker1.10 后有所改变,只有 RUN、COPY、ADD 指令会创建层,其他指令会创建临时的中间镜像,不会直接增加构建的镜像大小 。

  1. 使用多阶段构建镜像

    ​ 将 dockerfile 的构建配置环境分为软件的编译环境和运行环境,这种方式就是多阶段构建思路。

本站总访问量 本站总访客数 本文总阅读量
载入天数...载入时分秒...