本篇内容主要讲解“如何精简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
在构建一些基础镜像,比如 debian
、 busybox
,非常有用
用于构建超少镜像,比如构建一个包含所有库的二进制文件
关于 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)
总结一下:
用 ldd
查出所需的 .so 文件
将所有依赖压缩成 rootfs.tar
或 rootfs.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
到此,相信大家对“如何精简Docker镜像”有了更深的了解,不妨来实际操作一番吧!这里是天达云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!