共計 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 工具
非常方便構建小鏡像
這些超小的基礎鏡像,結合能生成靜態(tài)原生 ELF 文件的編譯語言,比如 C /C++,比如 Go,特別方便構建超小的鏡像。
cloudcomb-logo(C 語言開發(fā))就是用到了該原理,才能構建出 585 字節(jié)的鏡像。
redis 同樣使用 C 語言 開發(fā),看來也有很大的優(yōu)化空間,下面這個實驗,讓我們介紹具體的操作方法。
步驟 6: 提取動態(tài)鏈接的 .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]
執(zhí)行構建:
$ 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 語言天生就方便用來構建精簡鏡像,得益于它能方便的打包成包含靜態(tài)鏈接的二進制文件。
打個比方,你有一個 4 MB 大小的包含靜態(tài)鏈接的 Go 二進制,并且將其打進 scratch 這樣的基礎鏡像,你得到的鏡像大小也只有區(qū)區(qū)的 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 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!