type
status
date
slug
summary
tags
category
icon
password
文章状态
镜像 Cache 机制
Docker Daemon 通过
Dockerfile
构建镜像时,当发现即将新构建出的镜像与已有的某镜像重复时,可以选择放弃构建新的镜像,而是选用已有的镜像作为构建结果,也就是采取本地已经 cache 的镜像作为结果。注意事项:
- ADD 命令与 COPY 命令
Dockerfile
中的 ADD
和 COPY
命令会检查指定文件的内容变化。Docker 通过计算文件的唯一 hash 值来判断文件内容是否改变(MD5sum)。如果 hash 值未变,则认为文件内容未变,可以继续使用缓存;否则,缓存将失效。- RUN 命令存在外部依赖
当
RUN
命令涉及外部依赖(如 RUN apt-get update
),由于软件源的更新,缓存可能会导致不满足用户需求的情况。用户可以使用 --no-cache
参数来确保获取最新的外部依赖,例如:- 优化
Dockerfile
以利用缓存
为了更好地利用 Docker 的缓存机制,建议将静态的安装和配置命令尽可能放在
Dockerfile
的前部。这样可以确保这些静态内容在变化较少的情况下,后续的构建步骤能够更有效地利用缓存。传统构建流程
步骤一:先编译、打包(镜像一)
步骤二:将打包好的应用复制到镜像中(镜像二)
多阶段构建
multi-stage
旧版本的 docker 是不支持 multi-stage 的,只有 17.05 以及之后的版本才开始支持
虽然 Alpine 镜像已经很小了,但是它依旧包含了许多不必要的组件。那么有没有可能让我们的镜像里不包含包管理工具、SHELL、冗余的二进制文件,只包含最小的可运行系统,以及我们的语言 Runtime,或者核心的 glibc 依赖呢?
distroless
Google 内部精简镜像
官方目前已经提供了多数场景下所需要的镜像,比如:
- 适合静态编译语言运行的镜像:C, C++, Go, Rust
- 适合动态语言使用的镜像:Java, Python, Node
Dockerfile
最佳实践 BP
Dockerfile
的最佳实践是为了确保构建的 Docker 镜像更小、更高效、更安全、更易于维护。
目标
- 易管理
- 少漏洞
- 镜像小
- 层级少
- 利用缓存
- 置于独立目录 & 使用
.dockerignore
文件
使用
Dockerfile
构建镜像时最好是将其放置在一个新建的空目录下。然后将构建镜像所需要的文件添加到该目录中。为了提高构建镜像的效率,可在目录下新建一个 .dockerignore
文件来指定要忽略的文件和目录。- 使用多阶段构建
可使用多阶段构建来减少所构建镜像的大小以及层数。
- 避免安装不必要的包
为了降低复杂性、减少依赖、减小文件大小、节约构建时间,应避免安装任何不必要的包。
- 一个容器只运行一个进程
理想情况应保证在一个容器中只运行一个进程。将多个应用解耦到不同容器中,保证了容器的横向扩展和复用。如果无法避免同一镜像运行多进程,应选择合理的初始化进程(init process)。
- 镜像层数尽可能少
- 只有
RUN
、COPY
、ADD
指令会创建新层,其他指令创建临时层,不会增加镜像大小。 - 使用连接符
&&
将多条RUN
命令连接成一条指令集,以减少层数。
需在
Dockerfile
可读性(也包括长期的可维护性)和减少层数之间做一个平衡。- RUN 指令
为了保持
Dockerfile
文件的可读性,可理解性,以及可维护性,建议将长的或复杂的 RUN
指令用反斜杠 \
分割成多行。- 将多行参数排序
将多行参数按字母顺序排序。可以减少可能出现的重复参数(比如安装多个包时的软件包名)。也便于阅读和审查,提高可读性。
- 使用构建缓存
在镜像的构建过程中,Docker 会遍历
Dockerfile
中的指令,然后顺序执行。执行前 Docker 都会在缓存中查找。故编写 Dockerfile
时,应将变更频率低的编译指令优先构建,放在镜像底层,有效利用 build cache 。- 选择最优的基础镜像
尽可能使用官方仓库作为构建镜像的基础。 选择可以满足业务需求最优的 base image,以确保镜像大小和功能的最优平衡。推荐使用较小的 Alpine 镜像以及 distroless 的镜像。
- 独立复制文件
复制文件时,每个文件应独立复制,这确保某个文件变更时,只影响该文件对应的缓存。
通过遵循这些最佳实践,可以确保
Dockerfile
编写得更加高效和易于维护,达到上述目标。- 作者:yomax66
- 链接:https://yomax66.xyz//learning/Best%20Practices%20for%20Writing%20Dockerfiles
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。