都说容器大法好,可是假设没有Docker镜像,Docker该是多无趣啊。

是否还记得第一个接触Docker的时候,你从Docker Hub下拉的那个镜像呢?在那个处女镜像的基础上。你执行了容器生涯的处女容器。镜像的基石作用已经非常明显。在Docker的世界里,能够说是:No Image,No Container。

再进一步思考Docker镜像,大家可能非常快就会联想到下面几类镜像:

  • 1.系统级镜像:如Ubuntu镜像。CentOS镜像以及Debian容器等;

    2.工具栈镜像:如Golang镜像。Flask镜像,Tomcat镜像等;

    3.服务级镜像:如MySQL镜像,MongoDB镜像。RabbitMQ镜像等;

    4.应用级镜像:如WordPress镜像,DockerRegistry镜像等。

镜像林林总总。想要执行Docker容器。必须要有Docker镜像;想要有Docker镜像,必须要先下载Docker镜像。既然涉及到下载Docker镜像,自然会存在Docker镜像存储。谈到Docker镜像存储,那我们首先来聊聊Docker镜像大小方面的知识。

下面将从三个角度来分析Docker镜像的大小问题:Dockerfile与镜像、联合文件系统以及镜像共享关系。

Dockerfile与镜像
Dockerfile由多条指令构成,随着深入研究Dockerfile与镜像的关系,非常快大家就会发现。Dockerfile中的每一条指令都会相应于Docker镜像中的一层。

继续以例如以下Dockerfile为例:

FROM ubuntu:14.04
ADD run.sh /
VOLUME /data
CMD ["./run.sh"]

通过docker build以上Dockerfile的时候。会在Ubuntu:14.04镜像基础上,加入三层独立的镜像,依次相应于三条不同的命令。

镜像示意图例如以下:

镜像

有了Dockerfile与镜像关系的初步认识之后,我们再进一步联系到每一层镜像的大小。

不得不说,在层级化管理的Docker镜像中。有不少层大小都为0。

那些镜像层大小不为0的情况,归根结底的原因是:构建Docker镜像时,对当前的文件系统造成了改动更新。

而改动更新的情况主要有两种:

1.ADD或COPY命令:ADD或者COPY的作用是在docker build构建镜像时向容器中加入内容。仅仅要内容加入成功,当前构建的那层镜像就是加入内容的大小,如以上命令ADD run.sh /。新构建的那层镜像大小为文件run.sh的大小。

2.RUN命令:RUN命令的作用是在当前空的镜像层内执行一条命令,倘若执行的命令须要更新磁盘文件。那么全部的更新内容都在存储在当前镜像层中。

举例说明:RUN echo DaoCloud命令不涉及文件系统内容的改动,故命令执行完之后当前镜像层的大小为0;RUN wget http://abc.com/def.tar命令会将压缩包下载至当前文件夹下,因此当前这一层镜像的大小为:对文件系统内容的增量改动部分,即def.tar文件的大小。

联合文件系统
Dockerfile中命令与镜像层一一相应。那么是否意味着docker build完成之后。镜像的总大小=每一层镜像的大小总和呢?答案是肯定的。

依旧以上图为例:假设ubuntu:14.04镜像的大小为200MB,而run.sh的大小为5MB,那么以上三层镜像从上到下,每层大小依次为0、0以及5MB,那么终于构建出的镜像大小的确为0+0+5+200=205MB。

尽管终于镜像的大小是每层镜像的累加,可是须要额外注意的是:Docker镜像的大小并不等于容器中文件系统内容的大小(不包含挂载文件,/proc、/sys等虚拟文件)。个中缘由,就和联合文件系统有非常大的关系了。

首先来看一下这个简单的Dockerfile样例(假如在Dockerfile当前文件夹下有一个100MB的压缩文件compressed.tar):

FROM ubuntu:14.04
ADD compressed.tar /
RUN rm /compressed.tar
ADD compressed.tar /

1.FROM ubuntu:镜像ubuntu:14.04的大小为200MB;

2.ADD compressed.tar /: compressed.tar文件为100MB,因此当前镜像层的大小为100MB,镜像总大小为300MB。

3.RUN rm /compressed.tar:删除文件compressed.tar,此时的删除并不会删除下一层的compressed.tar文件。仅仅会在当前层产生一个compressed.tar的删除标记,确保通过该层将看不到compressed.tar,因此当前镜像层的大小也为0。镜像总大小为300MB。

4.ADD compressed.tar /:compressed.tar文件为100MB,因此当前镜像层的大小为300MB+100MB。镜像总大小为400MB。

分析完成之后,我们发现镜像的总大小为400MB。可是假设执行该镜像的话,我们非常快能够发如今容器根文件夹下执行du -sh之后。显示的数值并不是400MB,而是300MB左右。基本的原因还是:联合文件系统的性质保证了两个拥有compressed.tar文件的镜像层,仅仅会容器看到一个。同一时候这也说明了一个现状,当用户基于一个非常大,甚至好几个GB的镜像执行容器时。在容器内部查看根文件夹大小,发现居然仅仅有500MB不到,设置更小。

分析至此,有一点大家须要非常注意:镜像大小和容器大小有着本质的差别。

镜像共享关系
Docker镜像说大不大,说小不小。可是一旦镜像的总数上来之后,岂不是对本地磁盘造成非常大的存储压力?平均每一个镜像500MB,岂不是100个镜像就须要准备50GB的存储空间?

结果往往不是我们想象的那样,Docker在镜像复用方面设计得非常出色,大大节省镜像占用的磁盘空间。

Docker镜像的复用主要体如今:多个不同的Docker镜像能够共享同样的镜像层。

假设本地镜像存储中仅仅有一个ubuntu:14.04的镜像。我们以两个Dockerfile来说明镜像复用:

FROM ubuntu:14.04
RUN apt-get update
FROM ubuntu:14.04
ADD compressed.tar /

假设终于docker build构建出来的镜像名分别为image1和image2。因为两个Dockerfile均基于ubuntu:14.04。因此。image1和image2这两个镜像均复用了镜像ubuntu:14.04。

假设RUN apt-get update改动的文件系统内容为20MB,终于本地三个镜像的大小关系应该例如以下:

ubuntu:14.04: 200MB

image1:200MB(ubuntu:14.04)+20MB=220MB

image2:200MB(ubuntu:14.04)+100MB=300MB

假设仅仅是单纯的累加三个镜像的大小,那结果应该是:200+220+300=720MB,可是因为镜像复用的存在,实际占用的磁盘空间大小是:200+20+100=320MB,足足节省了400MB的磁盘空间。在此,足以证明镜像复用的巨大优点。

总结
学习Docker的同一时候,往往有三部分内容是分不开的,那就是Dockerfile。Docker镜像与Docker容器,分析Docker镜像大小也是如此。Docker镜像的大小,貌似平淡无奇,却是优化镜像,容器磁盘限额必须要涉及的内容。

本系列将通过下面多篇文章来分析Docker镜像:

1.深刻理解 Docker 镜像大小

2.事实上 docker commit 非常easy

3.不得不说的 docker save 与 docker export 差别

4.为什么有些容器文件动不得

5.打破 MNT Namespace 的容器 VOLUME

Docker镜像大小相关推荐

  1. modules node 太大了_如何将Node.js Docker镜像大小减小10倍

    对应用程序进行Docker化非常简单,有效,但是优化Docker Image的大小是棘手的部分. Docker易于使用,但是一旦应用程序开始扩展,镜像大小就会呈指数增长.通常,大多数情况下,应用程序的 ...

  2. 优化Docker镜像大小方案 2017年12月10日 17:54:46 阅读数:1774 标

    2019独角兽企业重金招聘Python工程师标准>>> 优化Docker镜像大小方案 2017年12月10日 17:54:46 阅读数:1774 标签: Docker 更多 个人分类 ...

  3. iso镜像添加软件包_超薄Docker容器-减少Docker镜像大小的指南

    Photo by William Warby on Unsplash 您是否曾经想过为什么您的单应用程序Docker容器会增长到400 MB? 或者,也许为什么一个只有几十MB的应用程序二进制文件会生 ...

  4. 缩减Docker镜像大小的方法

    对于刚接触容器的人来说,他们很容易被自己构建的 Docker 镜像体积吓到,我只需要一个几 MB 的可执行文件而已,为何镜像的体积会达到 1 GB 以上?本文将会介绍几个奇技淫巧来帮助你精简镜像,同时 ...

  5. 优化 ASP.NET Core Docker 镜像的大小

    在这容器化的世界里,我们已经很少直接通过文件发布来运行asp.net core程序了.现在大多数情况下,我们都会使用docker来运行程序.在使用docker之前,我们往往需要打包我们的应用程序.as ...

  6. docker构建python3容器、压缩python镜像大小

    需求 1.使用Docker构建一个python容器,用于运行python相关应用 2.基于Dockerfile构建python容器 3.镜像的体积需要尽量的小(OS和python采用最小化安装) Py ...

  7. Docker 入门系列(2)- Docker 镜像, 免 sudo 使用 docker 命令、获取查看、修改镜像标签、查找删除创建镜像、导入导出镜像

    1. 免 sudo 使用 docker 命令 如果还没有 docker group 就添加一个 sudo groupadd docker 将用户加入该 group 内 sudo gpasswd -a ...

  8. Docker学习(三)-----Docker镜像常用命令

    六.Docker镜像 镜像是Docker的三大组件之一 Docker运行容器前需要本地存在对应的镜像,如果本地不存,Docker会从镜像仓库下载 6.1Docker获取镜像 6.1.1查找镜像 我们可 ...

  9. Docker镜像优化

    Docker镜像优化 原文:Docker镜像优化 前言 上篇博文说到使用Visual Studio Tools for Docker帮助我们生成Dockerfile,现在我们讨论下生成的Dockerf ...

最新文章

  1. AngularJs表单自动验证
  2. Nature-2018-抗菌药物组合有望特异性治疗耐多药性的细菌感染
  3. 在线代码格式化,在线JSON校验格式化
  4. 我为什么要做游戏化教养项目
  5. linux服务器存放规划,规划适用于 Linux 和 UNIX 服务器的客户端部署
  6. 腾讯音视频实验室:基于音视频细分场景的技术创新探索
  7. 操作系统上机题目(多进程2)
  8. 小储云v1.782免授权版
  9. js元素事件的绑定与解绑,绑定事件的区别
  10. OpenCV:使用python-cv2实现视频的分解与合成
  11. 计算机毕业设计中民宿平台信息管理系统设计
  12. Java内存模型探秘
  13. Insurance 项目——Mybetis-generator生成
  14. 进制转换 pdf_浏览器中的二进制以及相关转换
  15. 最近尝试移植了一下java.awt/javax.swing
  16. 店铺淘口令怎么生成, 怎么生成店铺淘口令
  17. 51中断编程c语言,有关51单片机中断的形式和C语言编程格式[精选5篇]
  18. 用python画星空-用Python画一个超级月亮
  19. 上海亚商投顾:沪指录得6连阳 两市成交再度破万亿
  20. 只要心存美好便是岁月花开时

热门文章

  1. 雅虎的Mash-up 之路
  2. 深入理解Presto
  3. 判断输入的IP地址是否合法
  4. 你知道用git打补丁吗?
  5. qsort 三级排序
  6. js 弹出层的点击事件影响到底层的点击事件_聊一聊 Node.js 错误处理
  7. 复习Collection_迭代器使用细节_泛型_综合案例
  8. 数据结构链表之队列,Python3实现——7
  9. 怎样修改t3服务器地址,怎样修改t3服务器地址
  10. 使用pymysql进行数据库的增删改查