利用分层机制优化Docker Image

微信公众号:运维开发故事,作者:冬子&华子

1.Docker Image 分层存储

为了最大化重用 Image,加快运行速度,减少内存和磁盘的占用,Docker container 运行时所构造的运行环境,实际上是由具有依赖关系的多个 Layer 组成的。如图 1 所示,每一串数字 ID 就代表了一个 Docker Image Layer。当我们在 pull 一个 Docker Image 的时候我们会发现所有依赖的 Layer 文件将会被 download。图片图 1. Docker Image 分层示意图

例如我们一个 Docker App Image 的运行环境是在基础的 Docker Base Image 的基础上,叠加了包含例如 anaconda等各种工具的 Image,再叠加包含模型文档及其相关依赖库的 Image,以及包含了最终应用的code包的 layer。这些 Image 由 AUFS 文件系统加载合并到统一路径中,以只读的方式存在,最后再叠加加载一层可写的空白的 Layer 用作记录对当前运行环境所作的修改。因此,当 Docker Image 每次由一个基础 Image 创建后,新 Image 就自动增加了一层。如图 2 所示图片 图 2. Docker Image Layer 的叠加

2 Docker Image 衍生单一 Base Image

随着项目基于 Docker 的使用逐渐增加,Docker Image 的数量也将逐渐增加。随之而来的问题就是如何维护这些 Docker Image 的升级。如果缺乏规划和设计,每个 Docker Image 均来自一个最基础的 OS Image,那么就需要对于所有的 Docker Image 进行重构。如图 3所示:

图片

图 3. Docker Image 衍生单一 Base Image

当环境进行更新升级的时候,如果所有的节点均来自一个基础的 OS Image,重复的 layer 层将会被重复更新。也就意味着,这部分重复的内容会被反复的下载。如果一个 Docker Image 达到了 1G 以上的规模,而每个 Docker Host 节点的更新都需要重新下载新的 Image. 这样环境更新所花费的时间将会是成倍的增加。如图 4 所示,Docker Image 2 和 Docker Image3 均是基于 Docker Image 1图片

  图 4. 基于同样 Base Image 的 Docker Image Layer 的叠加

图片

img

图 5. Docker Image Layer 在 Docker Host 上的存储关系

扫描二维码关注公众号,回复: 14416096 查看本文章

从图 5 可以看出在同一个 Docker host 上 download 来自同样 Base Image 的 Docker Image, Docker 在下载 Image layer 的时候,对于已经存在的 layer 是不会重复下载的。但是如果 layer 不同,即使内部包含的内容一样,也还是会重复下载的.

3.利用分层机制优化 Docker Image

通过上两节的介绍,可以发现缺乏良好设计的 Docker Image 会给日后的维护以及我们后续CICD的效率带来较大的问题。接下来就介绍下如何利用分层机制对项目的 Docker Image 进行合理的规划。从而提升 Docker 在CICD过程中的可持续性,并提升CICD的效率。

3.1 设计基于分层机制的 Docker Image

假设系统中我们有两个应用 App1 和 App2。这两个节点的环境信息如下:

分类 APP1 APP2
基础环境镜像 (os) Python3.7 Python3.7
安全组件(Security tools) some-security-framework some-security-framework
通用工具(General tools) make/gcc/path/wget/sudo/tar make/gcc/path/wget/sudo/tar
依赖库(Library) pip install -y some-dependences pip install -y some-dependences
模型组件(Model) some-path/dust.model some-path/dust.model
代码(Code) code.1 code.2
配置(Config) app1.conf app2.conf

通过上表环境信息的对比,我们发现在这两个不同引用的节点上,不同的部分只是 最后的代码code 的和config 文件。对于其他相同的部分,我们可以考虑通过 Docker Image Layer 的概念将其复用。从而最大限度发挥 Docker 的能力。将上表中的两部分环境信息以分类为节点名,重新以树状结构组织如图 6 所示。

图片

图6.环境配置树状图 1

建议将一些不会经常发生变化的命令或者同类型的命令,合并到同一层。如图 7 所示:

图片

图7.环境配置树状图 2

最后将图中的两个树状结构图进行叠加将重复的节点进行合并,最后得出如下树状结构图:

图片

图 8. 环境配置树状图 3

现在我们已经基于 Docker Image 的分层存储机制完成了一个初步的Docker Image 的规划。接下来就可以根据上图结构分别制作 Image。最终我们将会有三个 Base Image,和最终加入代码的业务镜像。同时基于此,我们的Dockerfile也类比如下:这里本该是 4个 gitlab 仓库制作的 4个镜像。为了方便展示镜像复用关系, 用一个代码块展示

# f1: 运维安全团队增加优化基础安全组件
FROM python3
RUN apt install -y some-security-framework
# push: abc.hub.com/libary/python3 

# f2: 架构师安装基础架构
FROM abc.hub.com/libary/python3
RUN wget -c anaconda12.sh && ./anaconda12.sh && rm -f anaconda12.sh
# push: abc.hub.com/ai-tools/env-anaconda:12

# f3: 制作模型镜像
FROM abc.hub.com/ai-tools/env-anaconda:12
RUN pip install -y some-dependences
RUN wget -c s3.xx.com/some-path/dust.model -O /some/path
# push: abc.hub.com/ai-tools/env-anaconda-dust:runtime

# f4: 制作业务镜像
FROM abc.hub.com/rk-ai-tools/env-anaconda-dust:runtime
ADD code /workspace/code
ENTRYPOINT [ "/bin/bash", "/entrypoint.sh" ]
# push: abc.hub.com/rk-ai-pollution/srv-some-appname-amd64:1.0.0-1234567

3.2 基于分层机制的 Docker Image 的实践

如图 10 所示, 按照之前介绍的安装 Security tools/General tools/Library 的Docker Image 大小在 1.8 G 左右。以此为基础创建的的 App Image 的大小在 1.9G 左右。

图片图 10. Docker Image 分层存储实验 1

在一个已经 download 了 Liberty Docker Image 的环境下下载 App Image。如图 11 所示,可以看到已经存在的 layer 已经是 complete 状态。唯一 download 的部分只有新增加的 EAR 所产生的新的 layer。所需时间仅仅为 1 分 33 秒。

图片

图 11. Docker Image 分层存储实验 2

如果直接在一个不存在 Liberty Docker Image 的 server 上去 download App Docker Image, 如图 12 所示,我们可以看到所需要的时间将超过 7 分钟。

图片 图 12. Docker Image 分层存储实验 3

通过图 13 可以发现其他 layer 的 download 时间要超过 4 分钟,如果反复对这些重复的 Docker Image layer 进行下载更新,将会严重影响环境更新的效率。随着不同 Image 之间在 Docker Image Layer 上的差异越大,所花费的下载 Docker Image 的代价也将越大。

图片 图 13. Docker Image 分层存储实验 4

4.小结

通过上文的描述和实际测试可知,如果我们能把镜像做一个合理的分层,不但能缩短拉取镜像的时间,提高CICD的效率,更能划分不同团队不同人员的角色,每个人只专注自己职责相关的镜像,然后不同团队或同团队其他人员可以在其基础上,再构建自己的镜像,层层递进,最终制作一个业务发布的镜像。

公众号:运维开发故事

github:https://github.com/orgs/sunsharing-note/dashboard

博客**:https://www.devopstory.cn**

爱生活,爱运维

我是冬子先生,《运维开发故事》公众号团队中的一员,一线运维农民工,云原生实践者,这里不仅有硬核的技术干货,还有我们对技术的思考和感悟,欢迎关注我们的公众号,期待和你一起成长!

图片

猜你喜欢

转载自blog.csdn.net/wanger5354/article/details/125009360