文档章节

7 步精简 Docker 镜像(下)

兵戈天下
 兵戈天下
发布于 2017/06/20 07:33
字数 1003
阅读 43
收藏 1
点赞 1
评论 0

一张图掌握 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 环境 Storage Pool 用完解决方案:resize-device-mapper

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

憬薇 ⋅ 2017/05/02 ⋅ 0

精简压缩优化 Docker 镜像几百MB

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

a1010256340 ⋅ 04/26 ⋅ 0

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

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

zhugeaming2018 ⋅ 05/25 ⋅ 0

使用 Device Mapper来改变Docker容器的大小

如果在 CentOS 、 REHL 、 Fedor 或者其他默认没有 AUFS 支持的 Linux 发行版上使用 Docker ,你可能需要用到 Device Mapper 的存储插件。将这个插件设置为默认,它会把你所有的容器存储到一...

文艺小青年 ⋅ 2017/01/01 ⋅ 0

Docker Toolbox:联合Compose、Boot2Docker、Kitematic

有了Toolbox,桌面用户在使用Docker时,可以将一系列使用容器运行的app组合在一起,对于用户来说,这是一个由来已久的痛点。 桌面用户在使用Docker时,一直是分成几个独立的部分:精简的Boo...

苏宁公有云 ⋅ 2015/08/20 ⋅ 0

每天5分钟玩转Docker容器技术(三)

每天5分钟玩转Docker容器技术(一) 每天5分钟玩转Docker容器技术(二) base 镜像 上一节我们介绍了最小的 Docker 镜像,本节讨论 base 镜像。 base 镜像有两层含义: 不依赖其他镜像,从 ...

阿里云云栖社区 ⋅ 2017/12/27 ⋅ 0

Docker入门与实战系列:什么是Docker

Docker入门与实战——《Docker ABC》电子书 https://github.com/gudaoxuri/DockerABC 4. 什么是Docker 4.1. 权威解释 Docker is an open platform for building, shipping and running dist......

孤岛旭日 ⋅ 2015/11/07 ⋅ 0

Docker 存储池扩容

Docker 存储池扩容 如果在 CentOS 、 REHL 、 Fedor 或者其他默认没有 AUFS 支持的 Linux 发行版上使用 Docker ,你可能需要用到 Device Mapper 的存储插件。将这个插件设置为默认,它会把你...

超人学院 ⋅ 2015/05/29 ⋅ 0

Docker常见问题总结(持续更新)

一、镜像相关问题 1、如何批量清理临时镜像文件? #docker rmi $(DOCKER IMAGES -qf dangling=true) 2、如何查看镜像支持的环境变量? #docker run IMAGE env 3、本地的镜像文件都存放在哪里...

甘兵 ⋅ 2017/12/19 ⋅ 0

理解镜像(images)和容器(containers)

目录 开始使用Docker 在OS X安装Docker 理解镜像(images)和容器(containers) 搜索&运行whalesay镜像 构建你自己的镜像 创建Docker Hub账号(account)&库(repository) 标记(Tag),推送(Push),拉...

暗之幻影 ⋅ 2016/12/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL 数据库设计总结

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节...

OSC_cnhwTY ⋅ 今天 ⋅ 0

多线程(四)

线程池和Exector框架 什么是线程池? 降低资源的消耗 提高响应速度,任务:T1创建线程时间,T2任务执行时间,T3线程销毁时间,线程池没有或者减少T1和T3 提高线程的可管理性。 线程池要做些什...

这很耳东先生 ⋅ 今天 ⋅ 0

使用SpringMVC的@Validated注解验证

1、SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 [java] view plain copy edit.userna...

瑟青豆 ⋅ 今天 ⋅ 0

19.压缩工具gzip bzip2 xz

6月22日任务 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 6.1 压缩打包介绍: linux中常见的一些压缩文件 .zip .gz .bz2 .xz .tar .gz .tar .bz2 .tar.xz 建立一些文...

王鑫linux ⋅ 今天 ⋅ 0

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 今天 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 今天 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 今天 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 今天 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 今天 ⋅ 0

Linux(CentOS)下配置php运行环境及nginx解析php

【part1:搭建php环境】 1.选在自己需要安装的安装包版本,wget命令下载到服务器响应目录 http://php.net/releases/ 2.解压安装包 tar zxf php-x.x.x 3.cd到解压目录执行如下操作 cd ../php-...

硅谷课堂 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部