在docker鏡像創(chuàng)建過(guò)程中尸诽,鏡像少則幾百M(fèi),大則1G多硝皂,但是好奇的是鏡像每次的提交到遠(yuǎn)程速度超快。通過(guò)提交日志蛙吏,我們可以多少看出端倪源哩,Docker的文件系統(tǒng)是分塊管理的,如圖所示:
整個(gè)鏡像由多個(gè)用十六進(jìn)制Id標(biāo)記的layer組成鸦做,每次只提交被修改過(guò)的layer, 這也是dockert提交鏡像快速的秘密--增量提交励烦。
那Docker是怎么組織文件系統(tǒng)做到這一點(diǎn)的呢?
首先我們從Docker鏡像的結(jié)構(gòu)談起泼诱。Docker鏡像的一系列的layer坛掠,每一層代表了Dockerfile中的一條指令。比如下面的Dockerfile:
FROMubuntu:15.10
COPY. /app
RUN make/app
CMD java -jar /app/application.jar
它有四個(gè)指令治筒,每個(gè)指令生成一個(gè)層級(jí)屉栓,每一層都建立在前一個(gè)層級(jí)之上,他們是順序的層疊關(guān)系耸袜。下面是四個(gè)層級(jí)的展示層(最上層不屬于鏡像友多,它是容器的讀寫(xiě)層):
如果使用鏡像創(chuàng)建出了容器,那么存儲(chǔ)結(jié)構(gòu)如下堤框,多了容器的讀寫(xiě)層域滥,當(dāng)容器被刪除,讀寫(xiě)層會(huì)被刪除胰锌,鏡像的layer會(huì)保留骗绕,因此需要在容器中共享的靜態(tài)內(nèi)容需要都需要打包到鏡像文件中。下圖展示了容器的文件layer結(jié)構(gòu):
docker通過(guò)不同的storage driver來(lái)管理這些文件層級(jí)资昧,不同的driver有不同的實(shí)現(xiàn)酬土,并各有優(yōu)劣。但是格带,所有的drivers都是堆疊式的層級(jí)并且遵從CoW策略撤缴。
最后刹枉,我們來(lái)看看docker的卷(volume)。容器中任何修改過(guò)的屈呕,但是沒(méi)有寫(xiě)進(jìn)卷中的修改都會(huì)隨著容器的刪除而被移除微宝。如果你想保存容器中修改過(guò)的內(nèi)容,需要存儲(chǔ)在與volume關(guān)聯(lián)的docker host上的文件或者目錄中虎眨。下圖展示的是默認(rèn)的docker數(shù)據(jù)卷在docker host上存儲(chǔ)的位置蟋软。
從上面的三個(gè)方面可以看到,docker的整個(gè)文件結(jié)構(gòu)整個(gè)結(jié)構(gòu)由層疊的鏡像只讀層嗽桩,容器的讀寫(xiě)層以及存儲(chǔ)容器狀態(tài)數(shù)據(jù)的數(shù)據(jù)卷組成岳守。通過(guò)本文,我們?cè)敿?xì)的了解了docker組織文件的方式碌冶,有了它作為基礎(chǔ)湿痢,我們就可以更合理的配置和管理docker鏡像和容器。