文件系统_Docker文件系统实战
關(guān)鍵詞:Docker 聯(lián)合文件系統(tǒng) 鏡像 容器 云信私有化
在本文中,我們來實戰(zhàn)構(gòu)建一個Docker鏡像,然后實例化容器,在Docker的生命周期中詳細(xì)分析一下Docker的文件存儲情況和DockerFile優(yōu)化策略。
在開始實戰(zhàn)之前,我們先介紹一個概念,聯(lián)合文件系統(tǒng)(Union File System)。聯(lián)合文件系統(tǒng)是實現(xiàn)Docker鏡像的技術(shù)基礎(chǔ),支持對文件系統(tǒng)的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統(tǒng)下。鏡像的分層存儲和繼承就是基于此特性實現(xiàn)。
下面是Docker官方的一張描述文件系統(tǒng)的圖片,顯示了一張聯(lián)合文件系統(tǒng)在串聯(lián)鏡像層和容器層起到的作用
Docker支持多種聯(lián)合文件系統(tǒng),常見的有aufs,deviceMapper,overlay,overlay2,本文章中使用的系統(tǒng)版本為debian9.1,Docker版本為17.06.2-ce,默認(rèn)使用是overlay2。
看到這里如果你已經(jīng)對Docker文件系統(tǒng)有了簡單的概念,那么讓我們開始實戰(zhàn),來對分層文件系統(tǒng)的存儲方式進(jìn)行更加深入的了解。
鏡像層
這是一個云信私有化項目中基于debian系統(tǒng)鏡像創(chuàng)建的jdk8基礎(chǔ)鏡像,為了方便閱讀和分析,我們Dockerfile進(jìn)行了一些精簡,只保留核心部分內(nèi)容
FROM hub.c.163.com/library/debian:stretch
MAINTAINER nim
#下載jdk
ADD http://10.173.11.100/nim/jdk-8u202-linux-x64.tar.gz /usr/local/nim/
#解壓jdk并刪除
RUN tar -xzvf /usr/local/nim/jdk-8u202-linux-x64.tar.gz -C /usr/local/nim/
&& rm /usr/local/nim/jdk-8u202-linux-x64.tar.gz
#設(shè)置環(huán)境變量
ENV JAVA_HOME=/usr/local/nim/jdk1.8.0_202
ENV PATH=$JAVA_HOME/bin:$PATH
CMD ["/bin/bash"]
根據(jù)構(gòu)建鏡像,查看構(gòu)建結(jié)果,原基礎(chǔ)鏡像100M,構(gòu)建后鏡像體積697M。
鏡像存儲
現(xiàn)在開始看一下構(gòu)建鏡像工作在文件層存儲情況。首先我們使用Docker history查看一下剛剛構(gòu)建鏡像情況,可以看到基礎(chǔ)鏡像占用100M,兩個鏡像分層占用194MB和403M。
接下來我們看查看一下文件系統(tǒng)中的存儲情況,本環(huán)境使用overlay2,Docker鏡像層存儲默認(rèn)路徑為/var/lib/Docker/overlay2/,可以看到鏡像存儲目錄下有4個目錄,其中110M的對應(yīng)是基礎(chǔ)鏡像,另外兩個為ADD JDK(186M)和解壓JDK壓縮包的鏡像分層(389M)。
其中的l目錄包含了所有層的軟連接,軟鏈接使用短名稱,避免mount時候參數(shù)達(dá)到頁面大小限制。
下面我們了解一下,每個分層中的文件內(nèi)容。基礎(chǔ)鏡像分層包含diff文件夾和link文件,diff文件夾中存放當(dāng)前分層內(nèi)容,link文件記錄短名稱。
接下來看一下COPY JDK生成的內(nèi)容,diff文件夾保存了jdk壓縮包,本層相比基礎(chǔ)鏡像層,多了lower,merged,work三個文件/文件夾,其中l(wèi)ower記錄了此層的下層ID(基礎(chǔ)鏡像層),merged目錄作為提供了統(tǒng)一視圖,在容器層讀寫層被使用,work目錄用于聯(lián)合掛載指定的工作目錄,使用過程對用戶不可見。
解壓JDK層的文件夾結(jié)構(gòu)內(nèi)容和上一層類似,主要關(guān)注jdk壓縮包占用空間為0,表示已被刪除。
現(xiàn)在來重點關(guān)注一個問題,鏡像大小等于所有分層相加,在后續(xù)分層中被刪除的jdk壓縮包仍然要占用存儲空間,這并不是我們原本意圖,因此這里就出現(xiàn)了鏡像文件進(jìn)行優(yōu)化的點。優(yōu)化后的Dockerfile如下
FROM hub.c.163.com/library/debian:stretch
MAINTAINER nim
RUN curl -o /usr/local/nim/jdk-8u202-linux-x64.tar.gz http://10.173.11.100/nim/jdk-8u202-linux-x64.tar.gz
&& tar -xzvf /usr/local/nim/jdk-8u202-linux-x64.tar.gz -C /usr/local/nim/
&& rm /usr/local/nim/jdk-8u202-linux-x64.tar.gz
&& export JAVA_HOME=/usr/local/nim/jdk1.8.0_202
&& export PATH=$JAVA_HOME/bin:$PATH
CMD ["/bin/bash"]
借這個優(yōu)化后的內(nèi)容,我們再談一下構(gòu)建Docker鏡像時在時間和空間可優(yōu)化的點:
1. 組合運行語句:合并相同類型構(gòu)建語句,可以有效減少鏡像分層;
2. 利用鏡像構(gòu)建緩存:時間同步,基礎(chǔ)軟件安裝等固定內(nèi)容在鏡像前部分處理,鏡像重新構(gòu)建時會使用緩存,節(jié)省時間;
3. 清理中間產(chǎn)物:注意安裝過程中使用的軟件和壓縮包在一定要同一層里清理,否則仍然會占用鏡像空間;
4. 構(gòu)建語句優(yōu)化:比如ADD在處理本地文件時可以直接解壓縮,起到COPY + RUN tar的作用;
5. 優(yōu)化基礎(chǔ)鏡像源:國內(nèi)高校和大型IT企業(yè)都有創(chuàng)建鏡像站,選擇一個穩(wěn)定更新及時的鏡像站可以有效縮短構(gòu)建時間;
舉例的鏡像中優(yōu)化策略涉及1,3條,用curl替代add,與解壓和刪除合并為一層,Dockerfile減少了層數(shù),清理中間過程的jdk安裝包,下圖是優(yōu)化后鏡像體積變化:
構(gòu)建鏡像真的是層數(shù)越少越好嗎?當(dāng)然不是這么絕對,尤其在早期鏡像版本不是很穩(wěn)定或是后續(xù)迭代比較頻繁時,合理的鏡像分層會減少編譯時間,降低出錯概率,也可以讓Dockerfile更具有可讀性。可以再穩(wěn)定版本形成之后對鏡像進(jìn)行二次優(yōu)化。
鏡像元數(shù)據(jù)
分析一個鏡像元數(shù)據(jù)我們主要關(guān)注三個目錄
/var/lib/Docker/image/overlay2/imaged/
/var/lib/Docker/image/overlay2/layerdb/
/var/lib/Docker/overlay2/
第一個目錄保存鏡像基礎(chǔ)元數(shù)據(jù),第二個目錄保存鏡像分層元數(shù)據(jù),第三個是上文提到的分層存儲目錄,保存實際分層內(nèi)容。下面就根據(jù)實際情況來看一下,元數(shù)據(jù)與存儲信息是如何關(guān)聯(lián)起來的。
Docker鏡像的基本信息保存在/var/lib/Docker/image/overlay2/imaged/content/sha256/下面,可以根據(jù)Docker image ID在此目錄下查找到對應(yīng)ID開頭文件。此文件中以json的形式保存了該鏡像的分層文件系統(tǒng)、構(gòu)建信息、相關(guān)容器等內(nèi)容。
第二個目錄/var/lib/Docker/image/overlay2/layerdb/sha256/保存分層元數(shù)據(jù),每一個分層元數(shù)據(jù)目錄下有cache-id,diff,size信息,其中cache-id對應(yīng)分層存儲層,diff關(guān)聯(lián)鏡像基礎(chǔ)元數(shù)據(jù)信息。
容器層
首先我們來啟動一個容器,掛載宿主機(jī)/opt/yunxin目錄到容器/usr/local/yunxin目錄
創(chuàng)建容器完成之后,在鏡像存儲目錄/var/lib/Docker/overlay2/會生成容器的初始層和讀寫層,兩者使用相同標(biāo)識,初始層后面多了-init。初始層中主要保存初始化容器環(huán)境時,與容器相關(guān)的環(huán)境信息,如容器主機(jī)名,主機(jī)host信息以及域名服務(wù)文件等;讀寫層用于容器的讀寫,Docker容器內(nèi)的進(jìn)程只對讀寫層擁有寫權(quán)限,而對其他層文件內(nèi)容只擁有讀權(quán)限。
接下來我們進(jìn)入容器操作進(jìn)行一系列操作,再根據(jù)結(jié)果分析一下讀寫層對于文件的保存和處理,下面是操作和對應(yīng)結(jié)果以及讀寫層實際文件存儲情況。
讀寫層中的merged文件夾提供了統(tǒng)一視圖,面向用戶展示聯(lián)合文件系統(tǒng)掛載完成的最終形態(tài)。
接下來我們再基于同一個鏡像啟動幾個容器實例,然后來查詢一下Docker容器使用空間,只有第一個容器由于上面修改文件只占用154k,新啟動的容器并沒有額外占用空間。可見基于同一個鏡像創(chuàng)建容器時,所有的容器共享鏡像層內(nèi)容,有效節(jié)約了空間。讀寫層只保存修改內(nèi)容,如果是操作鏡像層文件,Docker采用的是修改時復(fù)制策略(copy-on-write)。這時回頭再看一下第一節(jié)出現(xiàn)的兩張圖,會對Docker的文件系統(tǒng)有了更深的體會。
結(jié)語
Docker 鏡像和容器文件系統(tǒng)相關(guān)知識在云信私有化產(chǎn)品的鏡像管理和運維存儲管理方面作出理論支撐,但這只是深入了解Docker的開始。隨著時間的積淀和云信旗下IM、音視頻、點播以及眾多相關(guān)產(chǎn)品私有化工作的深入,更多的模塊和鏡像,更多的客戶和需求,更復(fù)雜的網(wǎng)絡(luò)和環(huán)境都逐漸呈現(xiàn)在我們面前。Docker作為構(gòu)建云信私有化服務(wù)的基礎(chǔ),只有更深入的去了解原理才能在使用中去更好的優(yōu)化產(chǎn)品和開展運維。希望我們能為用戶提供更可靠的云信私有化服務(wù),也希望能在后續(xù)的文章中能與大家分享更多關(guān)于Docker的知識。
關(guān)注網(wǎng)易云信,聽取最新前沿觀察,看最有價值技術(shù)干貨,學(xué)網(wǎng)易最新實踐經(jīng)驗。陪你從思考者成長為技術(shù)專家。
總結(jié)
以上是生活随笔為你收集整理的文件系统_Docker文件系统实战的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: r语言数据变量分段_R数据分析:用R语言
- 下一篇: 今奥无人机举证_【企业动态】今奥小飞无人