如何精简Docker镜像

87次阅读
没有评论

共计 3147 个字符,预计需要花费 8 分钟才能阅读完成。

本篇内容主要讲解“如何精简 Docker 镜像”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“如何精简 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) |  nbsp; nbsp; Memo |
|:---:|:--------|:-----------|:-----:|:---:|---------------:|:--------------------------------|
| 01 | redis | `ubuntu` | C | dyn | 347.3 |  nbsp; nbsp; base ubuntu |
| 02 | redis | `debian` | C | dyn | 305.7 |  nbsp; nbsp; base debian |
| 03 | redis | `debian` | C | dyn | 151.4 |  nbsp; nbsp; cmd chaining |
| 04 | redis | `debian` | C | dyn | 151.4 |  nbsp; nbsp; docker-squash |
| 05 | redis | `scratch` | C | dyn | 7.73 |  nbsp; nbsp; 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 镜像”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计3147字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)