Docker 镜像优化:减少镜像尺寸

Docker 镜像优化:减少镜像尺寸

2016年08月23日 10:15:10 阅读数:1366 标签: 下载编译应用指令镜像docker

版权声明:本文为博主原创文章,未经博主容许不得转载。 https://blog.csdn.net/broadview2006/article/details/80124932shell

引 言 
随着咱们对Docker 应用的持续使用,若是不加注意,那么镜像的尺寸就会变得愈来愈大。不少人在使用Docker 时会发现,团队定制化的Docker 镜像尺寸都至少有1GB 大。镜像越大就意味着编译和部署Docker 应用的时间会越长。所以,咱们须要减少须要部署的镜像的尺寸。它会抵消使用Docker 带来的好处,失去快速迭代开发和部署应用的能力。 
本文节将深刻讨论Docker 镜像层的技术细节以及它们是如何影响最终镜像的大小的。 
接下来,咱们将在研究Docker 镜像工做原理的过程当中,学习如何优化这些镜像层。编程

链 式 指 令 
Docker 镜像尺寸变大的一个缘由是不少对编译或运行无关的指令被引入到镜像中。一个常见的案例是打包元数据和缓存。在安装完编译和运行相关的依赖包以后,这些下载的文件就没有存在的必要了。相似clean 的指令能够在不少仓库(如Docker Hub)的Dockerfile 中发现,它们用于清理这类文件,例如: 
图片描述
可是,一个Docker 镜像的尺寸是每个独立镜像层的尺寸之和,这也就是联合文件系统的工做机制。所以,clean 步骤并无真正删掉相应的硬盘空间,可经过以下命令来查看: 
图片描述
记录显示,这里并不存在“负”的镜像层尺寸。因而,Dockerfile 中每个指令要么保持镜像尺寸不变,要么增长它的尺寸。同时,每一步还会引入新的元数据信息,使得总体尺寸在增大。 
为了下降整个镜像的尺寸,清除操做应该在同一镜像层中执行。因而,解决方案是将先前的多条指令合并成一条。当Docker 使用/bin/sh 来执行每一条指令时,咱们可使用Bourne shell 提供的&&操做符来实现连接,例如: 
图片描述
如今每个独立层的尺寸已经足够小了。因为独立镜像层的尺寸被减少,因而整个镜像的尺寸也随之减少。让咱们来确认一下它们的尺寸,操做以下: 
图片描述
图片描述
分离编译镜像和部署镜像 
Docker 镜像中另外一类无用文件是编译过程当中的依赖文件,例如在编译应用程序过程当中所依赖的源代码库,如编译文件和头文件。一旦应用程序编译完毕,这些文件就再也不有用,由于运行该应用仅须要相关的依赖库。 
例如,编译下面这个应用程序,它已经开发完毕并准备部署到Docker 云主机上。这是一个简单的Web 应用程序,采用Go 语言开发,代码树以下图所示。 
图片描述
hello.go 的内容以下: 
图片描述
图片描述
相应的Dockerfile 中记录了如何编译源代码和运行编译结果,内容以下: 
图片描述
接下来,咱们将展现这个Docker 镜像的尺寸是如何变大的,操做以下所示。 
1.首先,编译这个Docker 镜像并记录它的尺寸,操做以下: 
图片描述
2.而后,对比运行时实际应用程序的尺寸,操做以下: 
图片描述
用Go 语言编写应用程序以及编译代码的一个优点是,它能够生成一个单一可执行文件,这对部署很是方便。Docker 镜像中除去该可执行文件占据的空间,全都是Docker 基础镜像引入的无用文件。能够发现,来自基础镜像的文件使得整个镜像尺寸增长了将近100倍。 
一样,咱们能够优化这个最终的Docker 镜像并仅打包最后的hello 可执行文件和相关的依赖包,而后部署到生产环境。优化步骤以下所示。 
1.首先,复制运行容器中的可执行文件到Docker 宿主机,操做以下: 
图片描述
2.若是前面的依赖库是一个静态库,那这一步就已经完成了,直接进入下一步。可是,Go 工具编译时默认采用共享库机制,为了让二进制文件直接运行,还须要这些共享库,操做以下: 
图片描述
3.接下来,保存所有共享库到Docker 宿主机,采用docker cp –L 命令,操做以下: 
图片描述
4.建立一个新的Dockerfile 用于编译这个只有二进制(binary-only)的镜像。注意,如何使用ADD 指令将共享库添加到Docker 镜像中,操做以下: 
图片描述
5.如今,全部必要的文件都在这个“binary-only”的镜像中,文件夹中的目录结构树以下图所示。 
图片描述
6.最后,采用build/Dockerfile 文件编译这个用于部署的二进制Docker 镜像,最终生成的镜像将比原来的小,操做以下: 
图片描述
一样的方法能够用于编译其余应用,例如一般采用./configure && make && makeinstall 方式安装的那些软件。一样,能够用于那些解释性编程语言的应用程序,如Python、Ruby 或者PHP。可是,建立一个“运行时”的Ruby 语言的Docker 镜像还须要进行一些额外处理。这种优化技术的最佳实践案例是在一个可持续开发流程中的应用程序的场景,而且它因为镜像太大致使传输时间太长。 
相关图书 
图片描述
《高性能Docker》 
DockOne社区倾情翻译 
阅读本书将掌握Docker性能优化实践 
更快、更高效地部署容器,改善开发工做流 
【美】艾伦·埃斯皮诺萨 著 
陈杰 杨峰 夏彬 译 
2016年9月出版 
◎ 帮助读者改善其Docker 工做流,并保证应用在生产环境中顺利进行 
◎ 除了Docker 的基础知识外,还会学到如何优化Docker基础架构和大规模应用缓存

相关文章
相关标签/搜索