文档章节

7 步精简 Docker 镜像(下)

兵戈天下
 兵戈天下
发布于 2017/06/20 07:33
字数 1003
阅读 64
收藏 1

一张图掌握 Docker 命令

图注:一张图掌握 Docker 命令 - 完整版

介绍

查看 docker hub 中的一些镜像,我们有时能看到很多极小的镜像,比如:

REPOSITORY              TAG        VIRTUAL SIZE    LICENSE
---------------         ------     ------------    -------
busybox                 latest     2.43 MB         GPLv2
progrium/busybox        latest     4.785 MB        GPLv2
alpine                  3.1        5.025 MB        GPLv2

这么小的镜像是怎么做出来的呢?话接上文,接下来就介绍一些精简 Docker 镜像的终极手段!

精简步骤

步骤 5: 使用最精简的 base image

方法:使用 scratch 或者 busybox 作为基础镜像。

关于 scratch:

  • 一个空镜像,只能用于构建镜像,通过 FROM scratch
  • 在构建一些基础镜像,比如 debianbusybox,非常有用
  • 用于构建超少镜像,比如构建一个包含所有库的二进制文件

关于 busybox

  • 只有 1~5M 的大小
  • 包含了常用的 UNIX 工具
  • 非常方便构建小镜像

这些超小的基础镜像,结合能生成静态原生 ELF 文件的编译语言,比如C/C++,比如 Go,特别方便构建超小的镜像。

cloudcomb-logo(C语言开发) 就是用到了该原理,才能构建出 585 字节的镜像。

redis 同样使用 C语言 开发,看来也有很大的优化空间,下面这个实验,让我们介绍具体的操作方法。

步骤 6: 提取动态链接的 .so 文件

实验上下文:

$ cat /etc/os-release

NAME="Ubuntu"
VERSION="14.04.2 LTS, Trusty Tahr"
$ uname -a
Linux localhost 3.13.0-46-generic #77-Ubuntu SMP
Mon Mar 2 18:23:39 UTC 2015
x86_64 x86_64 x86_64 GNU/Linux

隆重推出 ldd:打印共享的依赖库

$ ldd  redis-3.0.0/src/redis-server
    linux-vdso.so.1 =>  (0x00007fffde365000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f307d5aa000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f307d38c000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f307cfc6000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f307d8b9000)

将所有需要的 .so 文件打包:

$ tar ztvf rootfs.tar.gz
4485167  2015-04-21 22:54  usr/local/bin/redis-server
1071552  2015-02-25 16:56  lib/x86_64-linux-gnu/libm.so.6
 141574  2015-02-25 16:56  lib/x86_64-linux-gnu/libpthread.so.0
1840928  2015-02-25 16:56  lib/x86_64-linux-gnu/libc.so.6
 149120  2015-02-25 16:56  lib64/ld-linux-x86-64.so.2

再制作成 Dockerfile:

FROM scratch
ADD  rootfs.tar.gz  /
COPY redis.conf     /etc/redis/redis.conf
EXPOSE 6379
CMD ["redis-server"]

执行构建:

$ docker build  -t redis-05  .

查看大小:

| Lab |         | Base       | PL    | .red[*] |  Size (MB) |    Memo               |
|:---:|:--------|:-----------|:-----:|:---:|---------------:|:--------------------------------|
|  01 |  redis  |  `ubuntu`  |   C   | dyn |   347.3        |    base ubuntu        |
|  02 |  redis  |  `debian`  |   C   | dyn |   305.7        |    base debian        |
|  03 |  redis  |  `debian`  |   C   | dyn |   151.4        |    cmd chaining       |
|  04 |  redis  |  `debian`  |   C   | dyn |   151.4        |    docker-squash      |
|  05 |  redis  |  `scratch` |   C   | dyn |    7.73        |    rootfs: .so        |

哇!显著提高啦!

测试一下:

$ docker run -d --name redis-05 redis-05

$ redis-cli  -h  \
  $(docker inspect -f '{{.NetworkSettings.IPAddress}}' redis-05)

$ redis-benchmark  -h  \
  $(docker inspect -f '{{.NetworkSettings.IPAddress}}' redis-05)

总结一下:

  1. ldd 查出所需的 .so 文件
  2. 将所有依赖压缩成 rootfs.tarrootfs.tar.gz,之后打进 scratch 基础镜像

步骤 7: 为 Go 应用构建精简镜像

Go 语言天生就方便用来构建精简镜像,得益于它能方便的打包成包含静态链接的二进制文件。

打个比方,你有一个 4 MB 大小的包含静态链接的 Go 二进制,并且将其打进 scratch 这样的基础镜像,你得到的镜像大小也只有区区的 4 MB。这可是包含同样功能的 Ruby 程序的百分之一啊。

这里再给大家介绍一个非常好用开源的 Go 编译工具:golang-builder,并给大家实际演示一个例子

程序代码:

package main // import "github.com/CenturyLinkLabs/hello"

import "fmt"

func main() {
    fmt.Println("Hello World")
}

Dockerfile:

FROM scratch
COPY hello /
ENTRYPOINT ["/hello"]

通过 golang-builder 打包成镜像:

docker run --rm \
    -v $(pwd):/src \
    -v /var/run/docker.sock:/var/run/docker.sock \
    centurylink/golang-builder

查看镜像大小(Mac下测试):

$ docker images
REPOSITORY   TAG      IMAGE ID       CREATED          VIRTUAL SIZE
hello        latest   1a42948d3224   24 seconds ago   1.59 MB

哇!这么省力,就能创建几 M 大小的镜像,Go 简介就是为 Docker 镜像量身定做的!

总结

  1. 优化基础镜像
  2. 串接 Dockerfile 命令:
  3. 压缩 Docker images
  4. 优化程序依赖
  5. 选用更合适的开发语言,比如 Go

参考

© 著作权归作者所有

共有 人打赏支持
兵戈天下
粉丝 5
博文 9
码字总数 10703
作品 0
杭州
高级程序员
精简压缩优化 Docker 镜像几百MB

转载:http://www.dockerinfo.net/3328.html 介绍 前段时间网易蜂巢曾经推出蜂巢 Logo T恤,用的正是 Docker 镜像制作,最神奇的是,它最终的镜像大小只有 585字节。 $ docker images grep h...

a1010256340
04/26
0
0
Docker 环境 Storage Pool 用完解决方案:resize-device-mapper

问题引出 今日笔者docker下出现诡异问题,在容器中vim编辑文件,保存是,一直提示 “E667: Fsync failed”,而且在同一个宿主机上的容器均有此问题,遂怀疑环境故障,且与存储相关,后偶然运...

憬薇
2017/05/02
0
0
精简Docker镜像的五种通用方法

精简Docker镜像的好处很多,不仅可以节省存储空间和带宽,还能减少安全隐患。优化镜像大小的手段多种多样,因服务所使用的基础开发语言不同而有差异。本文将介绍精简Docker镜像的几种通用方法...

Docker
08/23
0
0
「初级篇」跟我一起学docker(二)--核心概念和安装

环境介绍: 操作系统:64bit CentOS7 docker版本:17.05.0-ce(最新版本) 版本新功能: https://github.com/docker/docker/blob/master/CHANGELOG.md 安装步骤 系统:64位centos7 迅雷直接下...

zhugeaming2018
05/25
0
0
Docker | 第五章:构建自定义镜像

前言 上一章节,主要是介绍了下的一些常用命令的说明。我们知道,利用可以构建一个新的镜像,比如运行环境,就需要一个环境的镜像,但直接使用公共的镜像时,一般上大小都比较大。所以本章节...

oKong
08/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

驰狼课堂

http://www.chilangedu.com/

求是科技
10分钟前
0
0
jumpserver 报错"Incorrect string value

申明 本文所有内容参考自jumpserver记录命令无法入库问题 #1773 简介 jumpserver 1.4.0在jumpserver.log中大量报错,错误日志 File "/opt/jumpserver/apps/terminal/api.py", line 246, i...

zhnxin
16分钟前
1
0
用户管理相关配置文件及命令

9月19日任务 2.27linux和windows互传文件 3.1 用户配置文件和密码配置文件 3.2 用户组管理 3.3 用户管理 扩展知识 实用小工具 简单命令行下实现Linux/Windows文件互传 前提:使用远程工具Xsh...

robertt15
35分钟前
0
0
presto 架构

presto 介绍 是Facebook开源的,完全基于内存的并⾏计算,分布式SQL交互式查询引擎 是一种Massively parallel processing (MPP)架构,多个节点管道式执⾏ ⽀持任意数据源(通过扩展式Connect...

张欢19933
35分钟前
0
0
Ajax技术应用

1. 相关概述 1. ajax:即异步js与xml,可以实现客户端与服务端之间数据的异步交互。对于普通的B/S 模式是采用的同步方式,即一次请求必须等待一次服务器响应完成,而异步则是客户端发送请求后...

江左煤郎
35分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部