![詳解容器鏡像優(yōu)化_第1頁](http://file4.renrendoc.com/view5/M01/22/23/wKhkGGabiMeATH21AAGHYXn3a2g135.jpg)
![詳解容器鏡像優(yōu)化_第2頁](http://file4.renrendoc.com/view5/M01/22/23/wKhkGGabiMeATH21AAGHYXn3a2g1352.jpg)
![詳解容器鏡像優(yōu)化_第3頁](http://file4.renrendoc.com/view5/M01/22/23/wKhkGGabiMeATH21AAGHYXn3a2g1353.jpg)
![詳解容器鏡像優(yōu)化_第4頁](http://file4.renrendoc.com/view5/M01/22/23/wKhkGGabiMeATH21AAGHYXn3a2g1354.jpg)
![詳解容器鏡像優(yōu)化_第5頁](http://file4.renrendoc.com/view5/M01/22/23/wKhkGGabiMeATH21AAGHYXn3a2g1355.jpg)
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
對于剛接觸容器的人來說,很容易被自己制作的Docker鏡像大小所嚇到,我只需要一個幾MB的可執(zhí)行文件而已,為何鏡像的大小會達到1GB以上?下面將從兩方面來進行鏡像大小優(yōu)化,一種是通過多階段構建處理,一種是使用不同的基礎鏡像進行特定優(yōu)化與精簡。1減少鏡像大小這部分著重介紹多階段構建(multi-stagebuilds),因為這是鏡像精簡之路至關重要的一環(huán)。在這部分內容中,我會解釋靜態(tài)鏈接和動態(tài)鏈接的區(qū)別,它們對鏡像帶來的影響,以及如何避免那些不好的影響。我們還是從helloworld的程序開始,用C語言實現如下:然后為其編寫Dockerfile,如下:執(zhí)行Dockerbuild-thello:gcc.進行構建后,發(fā)現鏡像大小超過了1GB。因為該鏡像包含了整個gcc鏡像的內容。但其實編譯好的代碼可執(zhí)行文件只有8.4KB,這顯然不科學。換個安裝了C編譯器的Ubuntu鏡像看看,會得到一個大概300MB大小的鏡像,縮小了3倍,但還是比8.4KB大太多了。類似地,Go語言版本的helloworld會得到相同的結果:使用基礎鏡像golang構建的鏡像大小是800MB,而編譯后的可執(zhí)行文件只有2MB大小,看來這個起決定性因素的還是基礎鏡像,那我們如何減小呢?請采用多階段構建的方法。我們還是以C語言的來看看,要想大幅度減少鏡像的大小,多階段構建是必不可少的。多階段構建的想法很簡單:“我不想在最終的鏡像中包含一堆C或Go編譯器和整個編譯工具鏈,我只要一個編譯好的可執(zhí)行文件!”。多階段構建可以由多個FROM指令識別,每一個FROM語句表示一個新的構建階段,階段名稱可以用AS參數指定,例如:這里使用基礎鏡像gcc來編譯程序hello.c,然后啟動一個新的構建階段,它以ubuntu作為基礎鏡像,將可執(zhí)行文件hello從上一階段拷貝到最終的鏡像中。最終的鏡像大小是73.9MB,比之前的1.19GB減少了95%。在聲明構建階段時,可以不必使用關鍵詞AS,最終階段拷貝文件時可以直接使用序號表示之前的構建階段(從零開始)。也就是說,下面兩行是等效的:如果Dockerfile內容不是很復雜,構建階段也不是很多,可以直接使用序號表示構建階段。一旦Dockerfile變復雜了,構建階段增多了,最好還是通過關鍵詞AS為每個階段命名,這樣也便于后期維護。細心的你,可能會發(fā)現上面以ubuntu為基礎鏡像還是大了些,能不能選擇一個更小的鏡像呢?當然可以,我們可以采用busybox或alpine鏡像來替代該ubuntu鏡像。2精簡策略這部分將會針對不同的基礎鏡像進行精簡,比如scratch,alpine,slim等,還可以從語言層面進行精簡,會以golang語言為例進行分析。2.1golang精簡Go語言程序編譯時會將所有必須的依賴編譯到二進制文件中,但也不能完全肯定它使用的是靜態(tài)鏈接,因為Go的某些包是依賴系統(tǒng)標準庫的,例如使用到DNS解析的包。只要代碼中導入了這些包,編譯的二進制文件就需要調用到某些系統(tǒng)庫,為了這個需求,Go實現了一種機制叫cgo,以允許Go調用C代碼,這樣編譯好的二進制文件就可以調用系統(tǒng)庫。也就是說,如果Go程序使用了net包,就會生成一個動態(tài)的二進制文件,如果想讓鏡像能夠正常工作,必須將需要的庫文件復制到鏡像中,或者直接使用busybox:glibc鏡像。當然,你也可以禁止cgo,這樣Go就不會使用系統(tǒng)庫,使用內置的實現來替代系統(tǒng)庫(例如使用內置的DNS解析器),這種情況下生成的二進制文件就是靜態(tài)的??梢酝ㄟ^設置環(huán)境變量CGO_ENABLED=0來禁用cgo,例如:由于編譯生成的是靜態(tài)二進制文件,因此可以直接跑在scratch鏡像中(下面會介紹)。當然,也可以不用完全禁用cgo,可以通過-tags參數指定需要使用的內建庫,例如-tagsnetgo就表示使用內建的net包,不依賴系統(tǒng)庫:這樣指定之后,如果導入的其他包都沒有用到系統(tǒng)庫,那么編譯得到的就是靜態(tài)二進制文件。也就是說,只要還有一個包用到了系統(tǒng)庫,都會開啟cgo,最后得到的就是動態(tài)二進制文件。要想一勞永逸,還是設置環(huán)境變量CGO_ENABLED=0吧。2.2使用scratch鏡像scratch鏡像很小,因為它基本上是空的,除了Docker給它額外添加的metadata(元數據:描述數據的數據)。它是一個虛擬鏡像,不能被pull,也不能運行,因為它表示空!scratch鏡像不可以直接從Docker官方拉取下來,但可以用以下命令構建這個scratch鏡像:從鏡像大小可知,scratch鏡像大小為0,scratch構建鏡像時,可精簡到只在scratch上面加一層代碼生成的二進制可執(zhí)行文件??梢杂糜跇嫿╞usybox等超小鏡像,可以說是真正的從零開始構建屬于自己的鏡像。在構建二進制可執(zhí)行文件的時候,需要進行靜態(tài)編譯鏈接,因為scratch中沒有我們需要的動態(tài)鏈接庫。比如:CGO_ENABLED=0GOOS=linuxGOARCH=arm64gobuild-oempty–a-ldflags'-s'emptyImageProject/所以如果您追求鏡像極小的話,可以使用scratch鏡像配合多階段處理來構建業(yè)務鏡像。其缺點是:缺少shell,缺少調試工具、缺少libc等基礎庫。2.3使用scratch鏡像Alpine是眾多Linux發(fā)行版中的一員,和CentOS、Ubuntu、Archlinux之類一樣,只是一個發(fā)行版的名字,號稱小巧安全,有自己的包管理工具apk。與CentOS和Ubuntu不同,Alpine并沒有像RedHat或Canonical之類的大公司為其提供維護支持,軟件包的數量也比這些發(fā)行版少很多(如果只看開箱即用的默認軟件倉庫,Alpine只有10000個軟件包,而Ubuntu、Debian和Fedora的軟件包數量均大于50000。)容器崛起之前,Alpine還是個無名之輩,可能是因為大家并不是很關心操作系統(tǒng)本身的大小,畢竟大家只關心業(yè)務數據和文檔,程序、庫文件和系統(tǒng)本身的大小通??梢院雎圆挥嫛H萜骷夹g席卷整個軟件產業(yè)之后,大家都注意到了一個問題,那就是容器的鏡像太大了,浪費磁盤空間,拉取鏡像的時間也很長。于是,人們開始尋求適用于容器的更小的鏡像。對于那些耳熟能詳的發(fā)行版(例如Ubuntu、Debian、Fedora)來說,只能通過刪除某些工具(例如ifconfig和netstat)將鏡像體積控制在100M以下。而對于Alpine而言,什么都不用刪除,鏡像大小也就只有5M而已。Alpine鏡像的另一個優(yōu)勢是包管理工具的執(zhí)行速度非??欤惭b軟件體驗非常順滑。誠然,在傳統(tǒng)的虛擬機上不需要太關心軟件包的安裝速度,同一個包只需要裝一次即可,無需不停重復安裝。容器就不一樣了,你可能會定期構建新鏡像,也可能會在運行的容器中臨時安裝某些調試工具,如果軟件包的安裝速度很慢,會很快消磨掉我們的耐心。為了更直觀,我們來做個簡單的對比測試,看看不同的發(fā)行版安裝tcpdump需要多長時間,測試命令如下:既然apline鏡像除了小之外,工具包的安裝速度也快,那我們在挑選各種語言版本的基礎鏡像時,可以優(yōu)先選擇帶alpine的tag的鏡像。比如golang:alpine就提供了基于Alpine構建的Go工具鏈。生成的鏡像大小為7.5M,對于一個只打印helloworld的程序來說確實有點大了,但我們可以換個角度:即使程序很復雜,生成的鏡像也不會很大。包含了很多有用的調試工具。即使運行時缺少某些特殊的調試工具,也可以迅速安裝。Go語言搞定了,C語言呢?并沒有gcc:alpine這樣的鏡像啊。只能以Alpine鏡像作為基礎鏡像,自己安裝C編譯器了,Dockerfile如下:最后來對比一下不同構建方法得到的helloworld鏡像大小:使用基礎鏡像golang構建:805MB多階段構建,build階段使用基礎鏡像golang,run階段使用基礎鏡像ubuntu:66.2MB多階段構建,build階段使用基礎鏡像golang:alpine,run階段使用基礎鏡像alpine:7.6MB多階段構建,build階段使用基礎鏡像golang,run階段使用基礎鏡像scratch:2MB最終鏡像體積減少了99.75%,相當驚人了。2.4slim鏡像如果實在不想折騰,可以選擇一個折衷的鏡像xxx:slim。slim鏡像一般都基于Debian和glibc,刪除了許多非必需的軟件包,優(yōu)化了體積。如果構建過程中需要編譯器,那么slim鏡像不適合,除此之外大多數情況下還是可以使用slim作為基礎鏡像的。下面是主流的解釋型語言的Alpine鏡像和slim鏡像大小對比:再來舉個特殊情況的例子,同時安裝matplotlib,numpy和pandas,不同的基礎鏡像構建的鏡像大小如下:可以看到這種情況下使用Alpine并沒有任何幫助,即使使
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 中秋禮盒銷售合同范本
- 中國抗感染類藥物行業(yè)市場發(fā)展監(jiān)測及投資方向研究報告
- 住宅供暖改造合同范本
- 出口紙張采購合同范本
- 淺析單片機的應用
- 勞務攬承合同范本
- 加工糾紛合同范本
- 公司簽訂私人合同范例
- 勞務及材料合同范本
- 務工勞動合同范例
- 國家生態(tài)安全教育課例課件
- 精神科常見藥物中毒急救與護理
- 《小兒計劃免疫》課件
- 林下經濟產業(yè)現狀及發(fā)展重點分析
- 消防業(yè)務開拓方案
- 鑄牢中華民族共同體意識自評報告范文
- 漫畫物理之力學
- 單板硬件測試規(guī)范
- 關于市推動高新技術企業(yè)發(fā)展的調研報告
- 學校安防監(jiān)控維保方案
- 13J103-7《人造板材幕墻》
評論
0/150
提交評論