转载:http://www.dockerinfo.net/3328.html

介绍

前段时间网易蜂巢曾经推出蜂巢 Logo T恤,用的正是 Docker 镜像制作,最神奇的是,它最终的镜像大小只有 585字节。

$ docker images | grep hub.c.163.com/public/logoREPOSITORY                          TAG     IMAGE ID           CREATED      SIZEhub.c.163.com/public/logo  latest  6fbdd13cd204  11 days ago  585 B

这其中就用到了不少精简镜像的技术,尤其是针对 C 程序的优化和精简。但我们平常开发肯定不止用 C 语言,甚至有些镜像都不是我们自己来打包的(比如下载公共镜像),那是否有一些通用的精简 Docker 镜像的手段呢? 答案是肯定的 ,甚至有的镜像可以精简 98%。精简镜像大小的好处不言而喻,既节省了存储空间,又能节省带宽,加快传输。那好,接下来就请跟随我来学习怎么一步步精简 Docker 镜像吧。

镜像层(Layers)

在开始制作镜像之前,首先了解下镜像的原理,而这其中最重要的概念就是镜像层(Layers)。镜像层依赖于一系列的底层技术,比如文件系统(filesystems)、写时复制(copy-on-write)、联合挂载(union mounts)等,幸运的是你可以在很多地方学习到这些技术,这里就不再赘述技术细节。

总的来说,你最需要记住这点:

在 Dockerfile 中, 每一条指令都会创建一个镜像层,继而会增加整体镜像的大小。

举例来说:

FROM busyboxRUN mkdir /tmp/fooRUN dd if=/dev/zero of=/tmp/foo/bar bs=1048576 count=100RUN rm /tmp/foo/bar

以上 Dockerfile 干了这几件事:

  • 基于一个官方的基础镜像 busybox(只有1M多)
  • 创建一个文件夹(/tmp/foo)和一个文件(bar)
  • 为该文件分配了100M大小
  • 再把这个大文件删除

事实上,它最终什么也没做,我们把它构建成镜像看看(构建可以参考一期):

docker build -t busybox:test .

再让我们来对比下原生的 busybox 镜像大小和我们生成的镜像大小:

$ docker images | grepbusyboxbusybox    test     896c63dbdb96    2 seconds ago    106 MBbusybox    latest   2b8fd9751c4c    9 weeks ago      1.093 MB

出乎意料的是,却生成了 106 MB 的镜像。

多出了 100 M,这是为何?这点和 git 类似(都用到了Copy-On-Write技术),我用 git 做了如下两次提交(添加了又删除),请问 A_VERY_LARGE_FILE 还在 git 仓库中吗?

$ git add  A_VERY_LARGE_FILE$ git commit$ git rm  A_VERY_LARGE_FILE$ git commit

答案是: 在的 ,并且会占用仓库的大小。Git 会保存每一次提交的文件版本,而 Dockerfile 中每一条指令都可能增加整体镜像的大小,即使它最终什么事情都没做。

精简步骤

了解了镜像层知识,有助于我们接下来制作精简镜像。这里开始,以最常用的开源缓存软件 Redis 为例,从一步步试验,来介绍如何制作更精简的 Docker 镜像。

步骤 1:初始化构建 Redis 镜像

直接上 Dockerfile :

FROM ubuntu:trustyENV VER     3.0.0ENV TARBALL http://download.redis.io/releases/redis-$VER.tar.gz# ==> Install curl and helper tools...RUN apt-get updateRUN apt-get install -y  curl make gcc# ==> Download, compile, and install...RUN curl -L $TARBALL | tar zxvWORKDIR  redis-$VERRUN makeRUN make install#...# ==> Clean up...WORKDIR /RUN apt-get remove -y --auto-remove curl make gccRUN apt-get cleanRUN rm -rf /var/lib/apt/lists/*  /redis-$VER#...CMD ["redis-server"]

结合注释,读起来并不困难,用到的都是常规的几个命令,简要介绍如下:

  • FROM:顶头写,指定一个基础镜像,此处基于 ubuntu:trusty
  • ENV:设置环境变量,这里设置了 VER 和 TARBALL 两个环境变量
  • RUN:最常用的 Dockerfile 指令,用于运行各种命令,这里调用了 8 次 RUN 指令
  • WORKDIR:指定工作目录,相当于指令 cd
  • CMD:指定镜像默认执行的命令,此处默认执行 redis-server 命令来启动 redis

执行构建:

$ docker build  -t redis:lab-1  .

注:国内网络,更新下载可能会较慢

查看大小:

动辄就有 300多 M 的大小,不能忍,下面我们开始一步步优化。

步骤 2: 优化基础镜像

方法:选用更小的基础镜像。

常用的 Linux 系统镜像一般有 ubuntu、centos、debian,其中debian 更轻量,而且够用,对比如下:

REPOSITORY     TAG        IMAGE ID           VIRTUAL SIZE---------------           ------          ------------                ------------centos              7               214a4932132a     215.7 MBcentos              6               f6808a3e4d9e      202.6 MBubuntu              trusty       d0955f21bf24      188.3 MBubuntu              precise    9c5e4be642b7     131.9 MBdebian              jessie       65688f7c61c4      122.8 MBdebian              wheezy    1265e16d0c28      84.96 MB

替换 debian:jessie 作为我们的基础镜像。

优化 Dockerfile:

FROM debian:jessie#...

执行构建:

$ docker build  -t redis:lab-2  .

查看大小:

减少了42M,稍有成效,但并不明显。细心的同学应该发现,只有 122 MB 的 debian 基础镜像,构建后增加到了 305 MB,看来这里面肯定有优化的空间,如何优化就要用到我们开头说到的 Image Layer 知识了。

步骤 3:串联 Dockerfile 指令

方法: 串联你的 Dockerfile 指令(一般是 RUN 指令)。

Dockerfile 中的 RUN 指令通过 && 和 / 支持将命令串联在一起,有时能达到意想不到的精简效果。

优化 Dockerfile:

FROM debian:jessieENV VER     3.0.0ENV TARBALL http://download.redis.io/releases/redis-$VER.tar.gzRUN echo "==> Install curl and helper tools..."  && \     apt-get update                      && \   apt-get install -y  curl make gcc   && \  \   echo "==> Download, compile, and install..."  && \  curl -L $TARBALL | tar zxv  && \   cd redis-$VER               && \   make                        && \   make install                && \   ...   echo "==> Clean up..."  && \   apt-get remove -y --auto-remove curl make gcc  && \apt-get clean                                  && \   rm -rf /var/lib/apt/lists/*  /redis-$VER#...CMD ["redis-server"]

构建:

$ docker build  -t redis:lab-3  .

查看大小:

哇!一下子减少了 50%,效果明显啊!这是最常用的一个精简手段了。

步骤 4:压缩你的镜像

方法:试着用命令或工具压缩你的镜像。

docker 自带的一些命令还能协助压缩镜像,比如 export 和 import

$ docker run -d redis:lab-3$ docker export 71b1c0ad0a2b | docker import - redis:lab-4

但麻烦的是需要先将容器运行起来,而且这个过程中你会丢失镜像原有的一些信息,比如:导出端口,环境变量,默认指令。

所以一般通过命令行来精简镜像都是实验性的,那么这里再推荐一个小工具: docker-squash。用起来更简单方便,并且不会丢失原有镜像的自带信息。

下载安装:

https://github.com/jwilder/docker-squash#installation(复制此链接到浏览器打开)

压缩操作:

$ docker save redis:lab-3 \ | sudo docker-squash -verbose -t redis:lab-4  \ | docker load

注: 该工具在 Mac 下并不好使,请在 Linux 下使用

对比大小:

好吧,从这里看起来并没有太大作用,所以我只能说试着,而不要报太大期望。

精简压缩优化 Docker 镜像几百MB相关推荐

  1. Docker基础镜像操作系统基础镜像对比(参考官方文档),优化docker镜像

    目录: 一. 选择Docker基础镜像 操作系统基础镜像 1. busybox 2. Alpine 3. CentOS 4. Ubuntu 5. Debian 二.编程语言基础镜像 应用基础镜像 其它 ...

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

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

  3. Docker镜像优化

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

  4. Docker 镜像优化:从 1.16GB 到 22.4MB

    作者 | The Agile Crafter Docker 是一个供软件开发人员和系统管理员使用容器构建.运行和与分享应用程序的平台.容器是在独立环境中运行的进程,它运行在自己的文件系统上,该文件系统 ...

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

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

  6. Docker镜像压缩与优化

    现如今docker如此受人追捧,主要是因为它的轻量化.可以快速部署以及资源的利用.但是一个docker images质量的好与坏,主要取决于Dockerfile编写的质量.同样功能的镜像,但是不同的D ...

  7. Docker镜像压缩和优化

    背景 在构建Docker容器时,应该尽量想办法获得体积更小的镜像,因为传输和部署体积较小的镜像速度更快. 但RUN语句总是会创建一个新层,而且在生成镜像之前还需要使用很多中间文件,在这种情况下,该如何 ...

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

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

  9. docker镜像创建与优化

    1 . 创建镜像 有两种方法构建镜像: docker commit :将运行的容器保存成镜像 Dockerfile:自动构建 使用docker commit 创建镜像分为三步: 运行容器 修改容器 将 ...

最新文章

  1. python输入字符串转换为公式_将python字符串转化成长表达式的函数eval实例
  2. Ecplise软件Devices看到两个相同设备问题
  3. The evolution of cluster scheduler architectures--转
  4. SQL实战篇:SQL优化问题
  5. php控制字数方法,php处理字数过多的方法
  6. linux input输入子系统分析《二》:s3c2440的ADC简单驱动实例分析
  7. ASP.NET-第一天-数据库知识
  8. 设置vim默认显示行号
  9. 线性表建立学生信息表
  10. html/css椭圆运动
  11. Sql server添加示例数据库Northwind
  12. 安卓开发调用python脚本_android开发调用python脚本
  13. matlab cond函数
  14. 2022新版域名防红系统源码
  15. ATUO CAD 如何延伸线段?
  16. 常量指针(Pointer to const)与指针常量(Const pointer)
  17. 【历史上的今天】3 月 16 日:开源精神奠基人诞生;技术先驱为女儿发明拍照手机;Minix 开发者出生
  18. SELinux,查看 SELinux状态及关闭SELinux
  19. Java接口(笔记本USB接口案例)
  20. 【2021-07-23】JS逆向之某乎x_zes_96

热门文章

  1. 多任务学习MTL-MMOE
  2. getc与fgetc的区别
  3. GraphSense介绍
  4. 访问项目无法访问 此网站192.168.*** 拒绝了我们的连接请求。
  5. 器件选型电源篇-AC/DC电源模块选型及性能测试
  6. 推荐!非常好用的sql审核平台——Yearning
  7. 5分钟学会Linux上传文件和下载文件命令
  8. 应广单片机003烧录器自定义封装使用技巧
  9. gensim学习之corpora.Dictionary
  10. UE4 Matinee制作相机动画及其蓝图播放(UE4.11和UE4.19测试通过)