Docker镜像大小
都說(shuō)容器大法好,可是假設(shè)沒(méi)有Docker鏡像,Docker該是多無(wú)趣啊。
是否還記得第一個(gè)接觸Docker的時(shí)候,你從Docker Hub下拉的那個(gè)鏡像呢?在那個(gè)處女鏡像的基礎(chǔ)上。你執(zhí)行了容器生涯的處女容器。鏡像的基石作用已經(jīng)非常明顯。在Docker的世界里,能夠說(shuō)是:No Image,No Container。
再進(jìn)一步思考Docker鏡像,大家可能非常快就會(huì)聯(lián)想到下面幾類(lèi)鏡像:
-
1.系統(tǒng)級(jí)鏡像:如Ubuntu鏡像。CentOS鏡像以及Debian容器等;
2.工具棧鏡像:如Golang鏡像。Flask鏡像,Tomcat鏡像等;
3.服務(wù)級(jí)鏡像:如MySQL鏡像,MongoDB鏡像。RabbitMQ鏡像等;
4.應(yīng)用級(jí)鏡像:如WordPress鏡像,DockerRegistry鏡像等。
鏡像林林總總。想要執(zhí)行Docker容器。必須要有Docker鏡像;想要有Docker鏡像,必須要先下載Docker鏡像。既然涉及到下載Docker鏡像,自然會(huì)存在Docker鏡像存儲(chǔ)。談到Docker鏡像存儲(chǔ),那我們首先來(lái)聊聊Docker鏡像大小方面的知識(shí)。
下面將從三個(gè)角度來(lái)分析Docker鏡像的大小問(wèn)題:Dockerfile與鏡像、聯(lián)合文件系統(tǒng)以及鏡像共享關(guān)系。
Dockerfile與鏡像
Dockerfile由多條指令構(gòu)成,隨著深入研究Dockerfile與鏡像的關(guān)系,非常快大家就會(huì)發(fā)現(xiàn)。Dockerfile中的每一條指令都會(huì)相應(yīng)于Docker鏡像中的一層。
繼續(xù)以例如以下Dockerfile為例:
通過(guò)docker build以上Dockerfile的時(shí)候。會(huì)在Ubuntu:14.04鏡像基礎(chǔ)上,加入三層獨(dú)立的鏡像,依次相應(yīng)于三條不同的命令。
鏡像示意圖例如以下:
鏡像
有了Dockerfile與鏡像關(guān)系的初步認(rèn)識(shí)之后,我們?cè)龠M(jìn)一步聯(lián)系到每一層鏡像的大小。
不得不說(shuō),在層級(jí)化管理的Docker鏡像中。有不少層大小都為0。
那些鏡像層大小不為0的情況,歸根結(jié)底的原因是:構(gòu)建Docker鏡像時(shí),對(duì)當(dāng)前的文件系統(tǒng)造成了改動(dòng)更新。
而改動(dòng)更新的情況主要有兩種:
1.ADD或COPY命令:ADD或者COPY的作用是在docker build構(gòu)建鏡像時(shí)向容器中加入內(nèi)容。僅僅要內(nèi)容加入成功,當(dāng)前構(gòu)建的那層鏡像就是加入內(nèi)容的大小,如以上命令A(yù)DD run.sh /。新構(gòu)建的那層鏡像大小為文件run.sh的大小。
2.RUN命令:RUN命令的作用是在當(dāng)前空的鏡像層內(nèi)執(zhí)行一條命令,倘若執(zhí)行的命令須要更新磁盤(pán)文件。那么全部的更新內(nèi)容都在存儲(chǔ)在當(dāng)前鏡像層中。
舉例說(shuō)明:RUN echo DaoCloud命令不涉及文件系統(tǒng)內(nèi)容的改動(dòng),故命令執(zhí)行完之后當(dāng)前鏡像層的大小為0;RUN wget http://abc.com/def.tar命令會(huì)將壓縮包下載至當(dāng)前文件夾下,因此當(dāng)前這一層鏡像的大小為:對(duì)文件系統(tǒng)內(nèi)容的增量改動(dòng)部分,即def.tar文件的大小。
聯(lián)合文件系統(tǒng)
Dockerfile中命令與鏡像層一一相應(yīng)。那么是否意味著docker build完成之后。鏡像的總大小=每一層鏡像的大小總和呢?答案是肯定的。
依舊以上圖為例:假設(shè)ubuntu:14.04鏡像的大小為200MB,而run.sh的大小為5MB,那么以上三層鏡像從上到下,每層大小依次為0、0以及5MB,那么終于構(gòu)建出的鏡像大小的確為0+0+5+200=205MB。
盡管終于鏡像的大小是每層鏡像的累加,可是須要額外注意的是:Docker鏡像的大小并不等于容器中文件系統(tǒng)內(nèi)容的大小(不包含掛載文件,/proc、/sys等虛擬文件)。個(gè)中緣由,就和聯(lián)合文件系統(tǒng)有非常大的關(guān)系了。
首先來(lái)看一下這個(gè)簡(jiǎn)單的Dockerfile樣例(假如在Dockerfile當(dāng)前文件夾下有一個(gè)100MB的壓縮文件compressed.tar):
FROM ubuntu:14.04 ADD compressed.tar / RUN rm /compressed.tar ADD compressed.tar /1.FROM ubuntu:鏡像ubuntu:14.04的大小為200MB;
2.ADD compressed.tar /: compressed.tar文件為100MB,因此當(dāng)前鏡像層的大小為100MB,鏡像總大小為300MB。
3.RUN rm /compressed.tar:刪除文件compressed.tar,此時(shí)的刪除并不會(huì)刪除下一層的compressed.tar文件。僅僅會(huì)在當(dāng)前層產(chǎn)生一個(gè)compressed.tar的刪除標(biāo)記,確保通過(guò)該層將看不到compressed.tar,因此當(dāng)前鏡像層的大小也為0。鏡像總大小為300MB。
4.ADD compressed.tar /:compressed.tar文件為100MB,因此當(dāng)前鏡像層的大小為300MB+100MB。鏡像總大小為400MB。
分析完成之后,我們發(fā)現(xiàn)鏡像的總大小為400MB。可是假設(shè)執(zhí)行該鏡像的話,我們非常快能夠發(fā)如今容器根文件夾下執(zhí)行du -sh之后。顯示的數(shù)值并不是400MB,而是300MB左右。基本的原因還是:聯(lián)合文件系統(tǒng)的性質(zhì)保證了兩個(gè)擁有compressed.tar文件的鏡像層,僅僅會(huì)容器看到一個(gè)。同一時(shí)候這也說(shuō)明了一個(gè)現(xiàn)狀,當(dāng)用戶(hù)基于一個(gè)非常大,甚至好幾個(gè)GB的鏡像執(zhí)行容器時(shí)。在容器內(nèi)部查看根文件夾大小,發(fā)現(xiàn)居然僅僅有500MB不到,設(shè)置更小。
分析至此,有一點(diǎn)大家須要非常注意:鏡像大小和容器大小有著本質(zhì)的差別。
鏡像共享關(guān)系
Docker鏡像說(shuō)大不大,說(shuō)小不小。可是一旦鏡像的總數(shù)上來(lái)之后,豈不是對(duì)本地磁盤(pán)造成非常大的存儲(chǔ)壓力?平均每一個(gè)鏡像500MB,豈不是100個(gè)鏡像就須要準(zhǔn)備50GB的存儲(chǔ)空間?
結(jié)果往往不是我們想象的那樣,Docker在鏡像復(fù)用方面設(shè)計(jì)得非常出色,大大節(jié)省鏡像占用的磁盤(pán)空間。
Docker鏡像的復(fù)用主要體如今:多個(gè)不同的Docker鏡像能夠共享同樣的鏡像層。
假設(shè)本地鏡像存儲(chǔ)中僅僅有一個(gè)ubuntu:14.04的鏡像。我們以?xún)蓚€(gè)Dockerfile來(lái)說(shuō)明鏡像復(fù)用:
FROM ubuntu:14.04 RUN apt-get update FROM ubuntu:14.04 ADD compressed.tar /假設(shè)終于docker build構(gòu)建出來(lái)的鏡像名分別為image1和image2。因?yàn)閮蓚€(gè)Dockerfile均基于ubuntu:14.04。因此。image1和image2這兩個(gè)鏡像均復(fù)用了鏡像ubuntu:14.04。
假設(shè)RUN apt-get update改動(dòng)的文件系統(tǒng)內(nèi)容為20MB,終于本地三個(gè)鏡像的大小關(guān)系應(yīng)該例如以下:
ubuntu:14.04: 200MB
image1:200MB(ubuntu:14.04)+20MB=220MB
image2:200MB(ubuntu:14.04)+100MB=300MB
假設(shè)僅僅是單純的累加三個(gè)鏡像的大小,那結(jié)果應(yīng)該是:200+220+300=720MB,可是因?yàn)殓R像復(fù)用的存在,實(shí)際占用的磁盤(pán)空間大小是:200+20+100=320MB,足足節(jié)省了400MB的磁盤(pán)空間。在此,足以證明鏡像復(fù)用的巨大優(yōu)點(diǎn)。
總結(jié)
學(xué)習(xí)Docker的同一時(shí)候,往往有三部分內(nèi)容是分不開(kāi)的,那就是Dockerfile。Docker鏡像與Docker容器,分析Docker鏡像大小也是如此。Docker鏡像的大小,貌似平淡無(wú)奇,卻是優(yōu)化鏡像,容器磁盤(pán)限額必須要涉及的內(nèi)容。
本系列將通過(guò)下面多篇文章來(lái)分析Docker鏡像:
1.深刻理解 Docker 鏡像大小
2.事實(shí)上 docker commit 非常easy
3.不得不說(shuō)的 docker save 與 docker export 差別
4.為什么有些容器文件動(dòng)不得
5.打破 MNT Namespace 的容器 VOLUME
總結(jié)
以上是生活随笔為你收集整理的Docker镜像大小的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 论文浅尝 | 基于迭代的概率规则约束的知
- 下一篇: 使用flask调用接口去加载模型和数据集