Docker镜像优化指南:如何有效地压缩镜像体积并缩短构建时间?

时至今日,大家已经能够从多种Docker支持的存储驱动程序中做出选择,从而确保其与我们的实际环境以及用例切实吻合——然而,除非深入理解镜像层(更不用提镜像与容器本身),否则一般用户根本不会考虑这方面问题。很明显,这些简单而且缺乏吸引力的技术元素层虽然是构成镜像的基本条件,但却往往得不到高度关注——因为闪亮的新型工具往往比基本信息更能抓人眼球。

在今天的文章中,我们将探讨镜像体积及构建时间方面的话题——而这两项工作也已经成为用户们迫切需要实现的目标。

让我们首先着眼于镜像与层,对其概念加以阐述:

Docker镜像是一套由只读层外加部分元数据构成的标签化结构。

每个层都拥有自己的UUID,而且每个连续层都建立在其下的层之上。

每个Dockerfile指令都会生成一个新层。

看起来基本理念非常简单,且不需要再做过多解释,不过我曾经遇上过这样一个让人如坠雾里的Dockerfile:

FROM centos:7.1.1503

RUN yum -y install java-1.8.0-openjdk-devel-1:1.8.0.65-2.b17.el7_1.x86_64

RUN yum clean all

这个Dockerfile到底出了什么问题?这个嘛,其中第二个RUN命令并没能真正影响到镜像体积——虽然它看起来确实应该有效削减镜像大小。让我们重新审视Docker镜像与层的定义,并着重强调其中的语法表达:

Docker镜像是一套由只读层外加部分元数据构成的标签化结构。

每个层都拥有自己的UUID,而且每个连续层都建立在其下的层之上。

每个Dockerfile指令都会生成一个新层。

现在,可以明确看到该Dockerfile并没能优化镜像体积。无论如何,让我们进行深入探讨,看看这些yum缓存是如何被从镜像层当中移除出去的。

不过为了保证文章浅显易懂的特性,我们首先将关注范畴限定在AUFS存储驱动程序身上。AUFS存储驱动程序能够添加一个疏排文件以覆盖镜像中底部只读层内文件的存在,从而将其从层内删除出去。除此之外,大家可以推断出镜像的大小相当于各层体积的总和,而添加到Dockerfile中的每条附加指令都会进一步增加镜像的体积。

只要将两项RUN指令加以合并,我们就能轻松对上面提到的Dockfile进行修复:

FROM centos:7.1.1503

RUN yum -y install java-1.8.0-openjdk-devel-1:1.8.0.65-2.b17.el7_1.x86_64 &&

yum clean all

下面让我们构建并检查这两套镜像以证明其瘦身效果。大家需要执行docker build -t 以在Dockerfile所容纳的目录当中构建一套镜像。在此之后,我们会发现两套镜像的体积有所不同:

$ docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

combined-layers latest defa7a199555 4 seconds ago 407 MB

separate-layers latest b605eff36c7b About a minute ago 471.8 MB

大家应该能够轻松判断哪套镜像是通过哪个Dockerfile构建而成,但让我们进一步查看两套镜像各自包含的层:

$ docker history --no-trunc separate-layers

IMAGE CREATED CREATED BY SIZE

b605eff36c7b418aa30e315dc0a1d809d08a1ebb8e574e934b11f5ad7cd490dc 2 minutes ago /bin/sh -c yum clean all 2.277 MB

4c363330dc9057ce6285be496aa02212759ecfc75c4ad3a9a74e6e2f3dacb1dd 2
minutes ago /bin/sh -c yum -y install
java-1.8.0-openjdk-devel-1:1.8.0.65-2.b17.el7_1.x86_64 257.5 MB

173339447b7ec3e8cb93edc61f3815ff754ec66cfadf48f1953ab3ead6a754c5 8 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B

4e1d113aa16e0631795a4b31c150921e35bd1a3d4193b22c3909e29e6f7c718d 8
weeks ago /bin/sh -c #(nop) ADD
file:d68b6041059c394e0f95effd6517765405402b4302fe16cf864f658ba8b25a97 in
/ 212.1 MB

a2c33fe967de5a01f3bfc3861add604115be0d82bd5192d29fc3ba97beedb831 7
months ago /bin/sh -c #(nop) MAINTAINER The CentOS Project - ami_creator
0 B

$ docker history --no-trunc combined-layers

IMAGE CREATED CREATED BY SIZE

defa7a199555834ac5c906cf347eece7fa33eb8e90b30dfad5f9ab1380988ade 48
seconds ago /bin/sh -c yum -y install
java-1.8.0-openjdk-devel-1:1.8.0.65-2.b17.el7_1.x86_64 && yum
clean all 195 MB

173339447b7ec3e8cb93edc61f3815ff754ec66cfadf48f1953ab3ead6a754c5 8 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B

4e1d113aa16e0631795a4b31c150921e35bd1a3d4193b22c3909e29e6f7c718d 8
weeks ago /bin/sh -c #(nop) ADD
file:d68b6041059c394e0f95effd6517765405402b4302fe16cf864f658ba8b25a97 in
/ 212.1 MB

a2c33fe967de5a01f3bfc3861add604115be0d82bd5192d29fc3ba97beedb831 7
months ago /bin/sh -c #(nop) MAINTAINER The CentOS Project - ami_creator
0 B

这清楚地表明链式命令能帮助我们在对各层进行提交前进行清理工作,不过这并不意味着我们应当将一切都塞进单一层当中。如果大家重新审视以上命令的输出结果,就会发现两套镜像的3个最底层拥有着同样的UUID,这意味着两套镜像共享这些层(有鉴于此,docker
images命令才能够报告各镜像的虚拟体积)。

有人可能会说,如今磁盘空间的使用成本已经如此低廉,我们真的有必要如此纠结于所谓镜像体积吗?但除了缓存镜像层之外,大家还有其它方面需要关注。其中最重要的一点在于镜像的构建时间。简单来讲,如果大家能够复用某个层,则无需对其进行重新构建。另外,如果大家的镜像需要通过网络进行传输(例如在流程中分阶段进行构建推进),那么更为袖珍的镜像体积与缓存层运用能够显著节约传输时长(并降低网络流量负载),因为需要实际传输的镜像层中有相当一部分已经被整合在新版本镜像当中。

现在结论已经显而易见,大家应当尽可能减少Dockerfile顶层的指令数量,从而提高缓存复用比例并努力着眼于底层对Dockerfile进行变更。

考虑到以上各项因素,有些朋友可以认为优化程度最高的解决方案应当是将全部发生变更的元素塞进各自不同的层当中,从而清理每个层的执行流程;
但一般来讲,这种作法并不会简化工作负担。首先,Docker对层数做出了限制,即不可超过127个,而且大家最好与上限之间保持一定距离。包含有大量层的Dockerfile既不易于后期维护,也不太可能排除那些不必要的数据;

相反,其结果是我们会面对一套非常臃肿的镜像,且最好将其拆分成多个不同镜像。而更重要的是,层的实现并非毫无成本,具体取决于我们使用的存储驱动程序,由此造成的额外负担也有所区别。举例来说,在AUFS当中,每个层都会在面向镜像层堆栈中各现有文件的首次写入时给容器写入性能造成延迟,特别在文件体积庞大且存在于大量镜像层之下的情况当中。

因此在文章最后,我们需要再次强调:要想切实提升镜像体积优化效果并压缩构建时间,大家必须了解自己想要优化什么,并有意识地做出必要妥协。

1. 如果大家需要了解或者深入掌握容器中的层概念,请点击此处查看Docker说明文档。

2. 查看存储驱动程序说明文档以了解与其性能表现相关的各项细节信息。

3. 如果大家发现自己需要处理高强度写入工作负载,可以考虑使用数据分卷(它们会绕开存储驱动程序)。

本文转自d1net(转载)

时间: 2024-09-20 05:31:30

Docker镜像优化指南:如何有效地压缩镜像体积并缩短构建时间?的相关文章

【转载】Docker 镜像优化与最佳实践

阿里云高级研发工程师御坂在云栖TechDay41期的线下沙龙活动中分享了Docker镜像优化与最佳实践.本文为沙龙内容回顾. 从Docker镜像存储的原理开始,针对镜像的存储.网络传输,介绍如何在构建中对这些关键点进行优化.并介绍Docker最新的多阶段构建的功能,以解决构建依赖的中间产物问题. 镜像概念 镜像是什么? 从一个比较具体的角度去看,镜像就是一个多层存储的文件,相较于普通的ISO系统镜像来说,分层存储会带来两个优点: 一个是分层存储的镜像比较容易扩展,比如我们可以基于一个Ubuntu

Docker 镜像优化与最佳实践

云栖TechDay41期,阿里云高级研发工程师御坂带来Docker镜像优化与最佳实践.从Docker镜像存储的原理开始,针对镜像的存储.网络传输,介绍如何在构建中对这些关键点进行优化.并介绍Docker最新的多阶段构建的功能,以解决构建依赖的中间产物问题.   以下是精彩内容整理: 镜像概念 镜像是什么?从一个比较具体的角度去看,镜像就是一个多层存储的文件,相较于普通的ISO系统镜像来说,分层存储会带来两个优点,一个是分层存储的镜像比较容易扩展,比如我们可以基于一个Ubuntu镜像去构建我们的N

Docker Hub中超过30%的官方镜像包含高危漏洞

本文讲的是Docker Hub中超过30%的官方镜像包含高危漏洞,[编者的话]Docker Hub是一个供Docker开发者用来上传/下载容器镜像的地方.为了认识其应对安全风险的能力如何,我们对其中的镜像进行了一次细致的研究.结果我们惊奇的发现,超过三成的官方仓库包含的镜像疑有高安全风险. Docker Hub是一个供Docker开发者用来上传/下载容器镜像的地方.为了认识其应对安全风险的能力如何,我们对其中的镜像进行了一次细致的研究.结果我们惊奇的发现,超过三成的官方仓库包含的镜像疑有高安全风

Docker Hub 中超过 30% 的官方镜像包含高危漏洞

[编者的话]Docker Hub是一个供Docker开发者用来上传/下载容器镜像的地方.为了认识其应对安全风险的能力如何,我们对其中的镜像进行了一次细致的研究.结果我们惊奇的发现,超过三成的官方仓库包含的镜像疑有高安全风险. Docker Hub是一个供Docker开发者用来上传/下载 容器镜像的地方.为了认识其应对安全风险的能力如何,我们对其中的镜像进行了一次细致的研究.结果我们惊奇的发现,超过三成的官方仓库包含的镜像疑有高安全风险(如:Shellshock.Heartbleed.Poodle

阿里云部署Docker(5)----管理和发布您的镜像

出到这节,我在百度搜索了一下"阿里云部署Docker",突然发现怎么会有人跟我写的一样呢?哦,原来是其他博客系统的爬虫来抓取,然后也不会写转载自什么什么的.所以,我终于明白为什么那些大咖的文章总会在文章的开头写明,转载请注明原创来自xxx的.恩.get it,从这篇开始,我也要这样了. 本文欢迎转载,但要尊重本人劳动成果,转载注明转自"http://blog.csdn.net/minimicall/" http://blog.csdn.net/minimicall/

A5优化:SEO遵循《百度搜索优化指南》的重要性

随着网络市场需求的不断加大,搜索引擎优化技术成了互联网企业竞争市场份额的一大因素,可以说企业关键字没有高的排名就不会有好的销售业绩.因此,搜索引擎优化"SEO"工作成了不少IT人的"职业".通过诸多搜索引擎排名规则分析,然后适时对网站做出针对性的优化,而提升更多的商业关键字的排名.但是从"SEO"这个词出现依赖,就逐步的被划分到了两个行为: 第一类别"白帽SEO" 所谓的白帽SEO就是踏踏实实分析搜索引擎规则,一步步的改善网站

jQuery性能优化指南

jQuery性能优化指南,可以从以下12个方向考虑. 1,总是从ID选择器开始继承 2,在class前使用tag(标签名) 3,将jQuery对象缓存起来(在多次使用是,用一个中间变量代替,而不是总是用选择器)   4,对直接的DOM操作进行限制 5,注意尽量减少事件冒泡 6,推迟到 $(window).load   7,压缩JavaScript 8,尽量使用ID代替Class. 9,给选择器一个上下文   10,慎用 .live()方法(应该说尽量不要使用) 11,子选择器和后代选择器   1

Genesis-3D开源游戏引擎完整实例教程之跑酷游戏篇06:移动版优化指南

6.移动版优化指南 概述: 移动设备不同于目前的高端设备(Wii.Xbox 360和PS3),市场上的手机硬件是很有限的,并且所有的移动设备都是 不一样的.像Adroid手机,由于品牌和出厂年限的不同,有一部分手机相对整个市场而言是老旧的.较慢的.但是,作 为游戏开发者并不能因为这些老旧的设备,而摒弃这部分的市场,因为尤其在中国,这些手机占有了很大一部分市场份 额.那么如何保证好的游戏画面的同时,来保证游戏可以快速有效的运行,就是开发者在游戏开发初期应该考虑的问题 . 本文意旨在于给应用Gene

移动HTML 5前端性能优化指南

  前端工程师的菜!最近移动Html 5越来越火,想有一个体验流畅的Html 5 应用,这篇优化指南就别放过咯.腾讯的同学将关键的注意点与优化方法都总结出来,全文高能干货,非常值得深度学习 >>> 概述 PC优化手段在Mobile侧同样适用 在Mobile侧我们提出三秒种渲染完成首屏指标 基于第二点,首屏加载3秒完成或使用Loading 基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过1014KB Mobile侧因手机配置原因,除加载外渲染速度也是优化重点 基