page contents

优化Docker 镜像小技巧

Docker镜像,是Docker执行程序中的主要镜像。它们是“容器的蓝图”,提供了有关如何生成容器的说明。在本文中,我将介绍一些经常被忽视的概念,这些概念将有助于优化Docker镜像的开发和构建过程。

attachments-2021-01-JlowgFLz5ff7c31abc0c2.png

Docker镜像,是Docker执行程序中的主要镜像。它们是“容器的蓝图”,提供了有关如何生成容器的说明。在本文中,我将介绍一些经常被忽视的概念,这些概念将有助于优化Docker镜像的开发和构建过程。


你如何构建Docker镜像?

让我们从Docker构建过程开始。Docker构建是通过使用Docker CLI工具中的docker build命令触发。

docker build命令根据Dockerfile文件中指定的指令构建Docker镜像。Dockerfile是一个文本文档,其中包含用户组装镜像所有的有序命令。

Docker镜像由只读层组成。每层代表一个Dockerfile指令。这些层是堆叠在一起的,每个层都是上一层的增量。我认为这些层是缓存的一种形式。对只更改了的层进行更新,而不是对每个更改进行更新。

下面的示例描述了Dockerfile的内容:

FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
复制代码

该文件中的每条指令代表Docker镜像中的单独一层。以下是每条指令的简要说明:

  • FROM 使用ubuntu:18.04创建Docker镜像的一个层

  • COPY 从Docker客户端所在的目录添加文件

  • RUN 使用make指令构建你的应用程序

  • CMD 指定在容器中运行什么命令

在构建过程中执行这四个命令时,它们将在Docker镜像中创建层。

如果你想了解有关镜像和层的更多信息,可以在此处阅读有关它们的信息。


优化镜像构建过程

既然我们已经介绍了Docker的构建过程,我想分享一些优化建议,以帮助有效地构建镜像。

1. 临时容器

Dockerfile定义的镜像应生成短暂的容器。

在这种情况下,临时容器是指可以销毁,重建,并可以替换为新容器。临时容器可以认为是一次性的。每个实例都是新的,并且与以前的容器实例无关。

在开发Docker镜像时,你应该利用尽可能多的临时模式。

2. 不要安装不必要的软件包

尽量避免安装不必要的文件和软件包。

Docker镜像应保持精简,这有助于提高可移植性,缩短构建时间,降低复杂性并减小文件大小。例如,在大多数情况下,不要在容器上安装文本编辑器,不要安装任何非必需的应用程序或服务。

3. 实现.dockerignore文件

.dockerignore文件,是用来声明不会被镜像包括的文件和目录。这有助于避免将不必要的大文件或敏感文件打包进去,并避免将它们添加到公共镜像。

如果你也要排除与构建无关的文件而不重新构建源码库,请使用一个.dockerignore文件。它支持类似于.gitignore文件的排除模式。

4. 多行参数要排序

尽可能通过排序多行参数来简化以后的更改,这有助于避免程序包重复,并使列表更易于更新。这也使PR易于阅读和查看。在反斜杠\之前添加空格也有帮助。

5. 解耦应用

依赖于其他应用的应用程序被视为“耦合”。

在某些情况下,它们托管在同一主机或计算节点上,这在非容器部署中很常见,但对于微服务,每个应用程序应存在于其自己的单独容器中。将应用程序解耦到多个容器中,可以更轻松地水平伸缩和重用容器。例如,一个解耦的Web应用程序可能包含三个单独的容器,每个容器都有自己的唯一镜像:一个用于管理Web应用程序,一个用于管理数据库的容器以及一个用于管理缓存的容器。

将每个容器限制为一个进程是一个很好的经验法则。根据你的最佳判断,使容器尽可能保持干净和模块化。

如果容器相互依赖,则可以通过使用Docker容器网络来确保这些容器可以通信。

6. 层数尽量少

Docker构建中,只有RUN,COPY和ADD指令创建图层。其他指令会创建临时的中间镜像,最终不会增加构建的大小。

也可以将所需的组件复制到最终镜像中,这会使你可以在构建阶段中包含其他工具或调试信息,而无需增加最终镜像的大小。

7. 利用构建缓存

在构建镜像时,Docker会逐步、按顺序执行Dockerfile中的每个指令。在每条指令中,Docker都会在其缓存中搜索要使用的镜像,而不是创建新的镜像。这是Docker遵循的基本规则:

从该基本镜像派生的所有子镜像,与已在缓存中的镜像进行比较,以查看是否其中一个是使用完全相同的指令构建的。如果不一样,则缓存失效,重新构建。

对于ADD和COPY指令,将检查镜像文件中的内容,并与现有镜像中进行比较。如果文件中的任何内容(例如内容和元数据)发生了更改,则缓存将无效。

除了ADD和COPY命令之外,缓存不会查看容器中的文件,来确定缓存是否匹配。例如,在使用RUN apt-get -y命令时,不会检查容器中的更新文件是否存在缓存中。

缓存无效后,后续所有Dockerfile命令都会生成新镜像,并且不使用缓存。


在CI流水线中优化Docker镜像构建

首先,前面提到的所有优化概念对于在CI流水线中构建镜像都是有效的。如果Dockerfile发生了变化,那么利用缓存仍然是减少构建时间的最佳方法。

当构建Docker镜像是CI流水线的常规流程时,可以利用Docker层缓存(DLC)的功能来加快构建速度。DLC是一项很棒的功能。DLC会在任务中将创建的镜像层保存,然后在后续的构建中重用未更改的镜像层,而不是每次都重新构建整个镜像。

DLC可与执行程序(machine executor)或远程Docker环境(setup_remote_docker)一起使用。要注意的是,DLC仅在使用docker build,docker compose等命令创建Docker镜像时很有用。

如果你想了解有关DLC的更多信息,可以在文档中阅读有关它的信息。


总结

在本文中,我介绍了用于构建Docker镜像时的优化技术,将帮助你有效地开发Docker镜像,加快CI流水线的速度。


attachments-2021-01-VskPa4EW5ff7c352db12f.jpg

链接:https://dzone.com/articles/tips-for-optimizing-docker-builds

  • 发表于 2021-01-08 10:27
  • 阅读 ( 672 )
  • 分类:Docker

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章