這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
#減小鏡像尺寸有兩種方法
- 使用鏈式指令
- 分離編譯鏡像和部署鏡像
使用鏈式指令&&
構建曆史.png
個人覺得鏡像會變大的其中一個原因就是中繼資料的大量化,試想一下對於每個指令的執行,docker都會為該指令所在的層次打上中繼資料標籤。#####################即對於每一條指令都會打上中繼資料,鏡像總和=中繼資料總和+每一層鏡像總和
試想最壞的情況,待到有很多條構建指令時,且每一條構建語句中只有一條構建指令,那樣的中繼資料總和就會變得非常大了
################為瞭解決這個問題,我們使用&&進行鏈式指令,即將多條指令使用&&連結起來,使得一條構建語句中包含多個執行指令,這樣的話能夠有效減少中繼資料總和
當然還有一點不得不提的是:################為了整個鏡像層尺寸,清除操作應該在同一層中執行,即執行完當前指令需要清理環境時盡量在當前同一層使用&&進行清除之前使用的環境
分離編譯鏡像和部署鏡像
書中提到,docker鏡像的另一類無用檔案就是編譯過程中的依賴檔案,例如在編譯過程中應用到的依賴的原始碼庫,如編譯檔案和標頭檔。一旦應用程式編譯完畢,這些檔案就不再用到了。
書中提到個例子:
mkdir ~/docker/goapp
cd ~/docker/goapp
建立兩個檔案hello.go和Dockerfile
建立兩個檔案.png
vim hello.go
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter,r *http.Request) {
fmt.Fprintf(w,"hello docker for go")
}
func main(){
http.HandleFunc("/",handler)
http.ListenAndServe(":8080",nil)
}
hello.go.png
vim Dockerfile
FROM golang:1.4.2
ADD hello.go hello.go
RUN go build hello.go
EXPOSE 8080
ENTRYPOINT ["./hello"]
Dockerfile.png
然後開始編譯這個鏡像$ docker build -t go/largeapp .
整個鏡像569MB大小.png
#######################整個鏡像569MB大小
運行鏡像容器:$docker run --name golargeapp -d -p 8080:8080 go/largeapp
對比實際運行時的應用程式尺寸$ docker exec -it golargeapp /bin/ls -lh
查看到go的可執行檔只用5.6M.png
#######################查看到go的可執行檔只用5.6M.png
#######可以看出相差了100多倍的大小,依賴環境佔了99%,真是可怕!
為此,我們可以選擇最佳化這個最終的Docker鏡像打包最後的hello可執行檔(即應用程式)和相關依賴包 部署到生產環境
1.首先複製容器中的可執行檔到宿主機中
1.1 建立build檔案夾$mkdir ~/docker/goapp/build
1.2 複製hello $ cd ~/docker/goapp/
$docker cp -L golargeapp:/go/hello ./build
2.添加運行時的依賴環境(靜態庫等)使程式能夠直接運行。
2.1 首先查看運行該程式需要哪些靜態庫$ docker exec -it golargeapp /usr/bin/ldd hello
運行hello需要這些靜態庫.png
linux-vdso.so.1 (0x00007ffc26796000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f501a17f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5019dd6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f501a39c000)
2.2 從容器中複製這些靜態庫
$docker cp -L golargeapp:/lib/x86_64-linux-gnu/libpthread.so.0 ./build
$docker cp -L golargeapp:/lib/x86_64-linux-gnu/libc.so.6 ./build
$docker cp -L golargeapp:/lib64/ld-linux-x86-64.so.2 ./build
此時的目錄.png
3.到~/docker/goapp/build目錄去建立一個Dockerfile
$ cd ./build
$ vim Dockerfile
FROM scratch
這個是只有二進位的鏡像
ADD hello /app/hello
ADD libpthread.so.0 /lib/x86_64-linux-gnu/libpthread.so.0
ADD libc.so.6 /lib/x86_64-linux-gnu/libc.so.6
ADD ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
EXPOSE 8080
ENTRYPOINT ["/app/hello"]
二進位dockerfile.png
目錄結構.png
編譯構建鏡像
$ docker build -t gobinaryapp .
構建鏡像並查看到構建的鏡像只有7.85MB.png
############構建鏡像並查看到構建的鏡像只有7.85MB,相比之前的569MB,鏡像足足小了100倍
#####小小對比一下效果
先運行之前的鏡像
Run GoLargeApp.png
在運行後來編譯的二進位鏡像
Run GoBinaryApp.png
可見應用程式效果一樣,鏡像大小卻相差百倍呢~~>