您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“怎么精簡Docker鏡像”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!
前段時間網(wǎng)易蜂巢曾經(jīng)推出蜂巢 Logo
T恤,用的正是 Docker 鏡像制作,最神奇的是,它最終的鏡像大小只有 585
字節(jié)。
$ docker images | grep hub.c.163.com/public/logo REPOSITORY TAG IMAGE ID CREATED SIZE hub.c.163.com/public/logo latest 6fbdd13cd204 11 days ago 585 B
點擊此處,可以了解該鏡像的制作過程,這其中就用到了不少精簡鏡像的技術(shù),尤其是針對 C 程序的優(yōu)化和精簡。但我們平常開發(fā)肯定不止用 C 語言,甚至有些鏡像都不是我們自己來打包的(比如下載公共鏡像),那是否有一些通用的精簡 Docker 鏡像的手段呢? 答案是肯定的 ,甚至有的鏡像可以精簡 98%。精簡鏡像大小的好處不言而喻,既節(jié)省了存儲空間,又能節(jié)省帶寬,加快傳輸。那好,接下來就請跟隨我來學(xué)習(xí)怎么一步步精簡 Docker 鏡像吧。
在開始制作鏡像之前,首先了解下鏡像的原理,而這其中最重要的概念就是鏡像層(Layers)
。鏡像層依賴于一系列的底層技術(shù),比如文件系統(tǒng)(filesystems)、寫時復(fù)制(copy-on-write)、聯(lián)合掛載(union mounts)等,幸運的是你可以在很多地方學(xué)習(xí)到這些技術(shù),這里就不再贅述技術(shù)細節(jié)。
總的來說,你最需要記住這點:
在 Dockerfile 中, 每一條指令都會創(chuàng)建一個鏡像層,繼而會增加整體鏡像的大小。
舉例來說:
FROM busybox RUN mkdir /tmp/foo RUN dd if=/dev/zero of=/tmp/foo/bar bs=1048576 count=100 RUN rm /tmp/foo/bar
以上 Dockerfile 干了這幾件事:
基于一個官方的基礎(chǔ)鏡像 busybox(只有1M多)
創(chuàng)建一個文件夾(/tmp/foo)和一個文件(bar)
為該文件分配了100M大小
再把這個大文件刪除
事實上,它最終什么也沒做,我們把它構(gòu)建成鏡像看看(構(gòu)建可以參考一期):
docker build -t busybox:test .
再讓我們來對比下原生的 busybox 鏡像大小和我們生成的鏡像大?。?/p>
$ docker images | grep busybox busybox test 896c63dbdb96 2 seconds ago 106 MB busybox latest 2b8fd9751c4c 9 weeks ago 1.093 MB
出乎意料的是,卻生成了 106 MB 的鏡像。
多出了 100 M,這是為何?這點和 git 類似(都用到了Copy-On-Write技術(shù)),我用 git 做了如下兩次提交(添加了又刪除),請問 A_VERY_LARGE_FILE
還在 git 倉庫中嗎?
$ git add A_VERY_LARGE_FILE $ git commit $ git rm A_VERY_LARGE_FILE $ git commit
答案是: 在的 ,并且會占用倉庫的大小。Git 會保存每一次提交的文件版本,而 Dockerfile 中每一條指令都可能增加整體鏡像的大小,即使它最終什么事情都沒做。
了解了鏡像層知識,有助于我們接下來制作精簡鏡像。這里開始,以最常用的開源緩存軟件 Redis
為例,從一步步試驗,來介紹如何制作更精簡的 Docker 鏡像。
直接上 Dockerfile
:
FROM ubuntu:trusty ENV VER 3.0.0 ENV TARBALL http://download.redis.io/releases/redis-$VER.tar.gz # ==> Install curl and helper tools... RUN apt-get update RUN apt-get install -y curl make gcc # ==> Download, compile, and install... RUN curl -L $TARBALL | tar zxv WORKDIR redis-$VER RUN make RUN make install #... # ==> Clean up... WORKDIR / RUN apt-get remove -y --auto-remove curl make gcc RUN apt-get clean RUN rm -rf /var/lib/apt/lists/* /redis-$VER #... CMD ["redis-server"]
結(jié)合注釋,讀起來并不困難,用到的都是常規(guī)的幾個命令,簡要介紹如下:
FROM:頂頭寫,指定一個基礎(chǔ)鏡像,此處基于 ubuntu:trusty
ENV:設(shè)置環(huán)境變量,這里設(shè)置了 VER
和 TARBALL
兩個環(huán)境變量
RUN:最常用的 Dockerfile 指令,用于運行各種命令,這里調(diào)用了 8 次 RUN 指令
WORKDIR:指定工作目錄,相當于指令 cd
CMD:指定鏡像默認執(zhí)行的命令,此處默認執(zhí)行 redis-server 命令來啟動 redis
執(zhí)行構(gòu)建:
$ docker build -t redis:lab-1 .
注:國內(nèi)網(wǎng)絡(luò),更新下載可能會較慢
查看大?。?/strong>
| Lab | iamge | Base | Lang | .red[*] | Size (MB) | Memo | |:---:|:--------|:-----------|:-----:|:---:|---------------:|:--------------------------------| | 1 | redis | `ubuntu` | C | dyn | 347.3 | base ubuntu |
動輒就有 300多 M 的大小,不能忍,下面我們開始一步步優(yōu)化。
方法:選用更小的基礎(chǔ)鏡像。
常用的 Linux 系統(tǒng)鏡像一般有 ubuntu
、centos
、debian
,其中debian
更輕量,而且夠用,對比如下:
REPOSITORY TAG IMAGE ID VIRTUAL SIZE --------------- ------ ------------ ------------ centos 7 214a4932132a 215.7 MB centos 6 f6808a3e4d9e 202.6 MB ubuntu trusty d0955f21bf24 188.3 MB ubuntu precise 9c5e4be642b7 131.9 MB debian jessie 65688f7c61c4 122.8 MB debian wheezy 1265e16d0c28 84.96 MB
替換 debian:jessie
作為我們的基礎(chǔ)鏡像。
優(yōu)化 Dockerfile:
FROM debian:jessie #...
執(zhí)行構(gòu)建:
$ docker build -t redis:lab-2 .
查看大?。?/strong>
| Lab | image | Base | Lang | .red[*] | Size (MB) | Memo | |:---:|:--------|:-----------|:-----:|:---:|---------------:|:--------------------------------| | 01 | redis | `ubuntu` | C | dyn | 347.3 | base ubuntu | | 02 | redis | `debian` | C | dyn | 305.7 | base debian |
減少了42M,稍有成效,但并不明顯。細心的同學(xué)應(yīng)該發(fā)現(xiàn),只有 122 MB 的 debian
基礎(chǔ)鏡像,構(gòu)建后增加到了 305 MB,看來這里面肯定有優(yōu)化的空間,如何優(yōu)化就要用到我們開頭說到的 Image Layer
知識了。
方法: 串聯(lián)你的 Dockerfile 指令(一般是 RUN
指令)。
Dockerfile 中的 RUN 指令通過 &&
和 /
支持將命令串聯(lián)在一起,有時能達到意想不到的精簡效果。
優(yōu)化 Dockerfile:
FROM debian:jessie ENV VER 3.0.0 ENV TARBALL http://download.redis.io/releases/redis-$VER.tar.gz RUN echo "==> Install curl and helper tools..." && \ apt-get update && \ apt-get install -y curl make gcc && \ \ echo "==> Download, compile, and install..." && \ curl -L $TARBALL | tar zxv && \ cd redis-$VER && \ make && \ make install && \ ... echo "==> Clean up..." && \ apt-get remove -y --auto-remove curl make gcc && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /redis-$VER #... CMD ["redis-server"]
構(gòu)建:
$ docker build -t redis:lab-3 .
查看大?。?/p>
| Lab | Image | Base | Lang | .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 |
哇!一下子減少了 50%,效果明顯啊!這是最常用的一個精簡手段了。
方法:試著用命令或工具壓縮你的鏡像。
docker 自帶的一些命令還能協(xié)助壓縮鏡像,比如 export
和 import
$ docker run -d redis:lab-3 $ docker export 71b1c0ad0a2b | docker import - redis:lab-4
但麻煩的是需要先將容器運行起來,而且這個過程中你會丟失鏡像原有的一些信息,比如:導(dǎo)出端口,環(huán)境變量,默認指令。
所以一般通過命令行來精簡鏡像都是實驗性的,那么這里再推薦一個小工具: docker-squash。用起來更簡單方便,并且不會丟失原有鏡像的自帶信息。
下載安裝:
壓縮操作:
$ docker save redis:lab-3 \ | sudo docker-squash -verbose -t redis:lab-4 \ | docker load
注: 該工具在 Mac 下并不好使,請在 Linux 下使用
對比大小:
| Lab | Image | 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 |
“怎么精簡Docker鏡像”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。