上期的文章: Kubernetes入門實踐--部署運行Go項目 發佈後,有網友留言說我文章裏演示的鏡像是把項目文件和Go都打包到了鏡像裏,這樣鏡像的佔用空間會比較大。
Go
開發的程序在編譯成二進制文件後是可以在沒有安裝 Go
環境的系統裏執行的,如果只把編譯完的二進制文件直接放到鏡像裏就能節省很多鏡像空間了。我給的回覆是文章的側重點是 Kubernetes
的實踐所以鏡像方面就沒有佔太多篇幅。
確實線上項目的應用鏡像一般都不像之前文章裏講的那樣構建,因爲生產項目各方面要求更嚴格些。鏡像構建的過程一般都是先用 Docker
容器把項目編譯成二進制文件,然後把編譯好的文件拷貝到一個新的容器鏡像裏,新鏡像裏一般只包含 Linux
系統運行需要的最基本的文件,不需要有 Go
環境,因此能減少很多佔用空間。整個這個過程都發生在鏡像構建的過程中,這樣就能保證多環境的一致性,上面這個構建 Docker
鏡像的方式叫做多階段構建( multi stage build
)。
多階段構建是 17.05
版本纔有的功能,所以使用前要先確定下使用的 Docker Engine
的版本。
下面就來介紹一下怎麼使用 Docker
的多階段構建制作 Go
應用的鏡像。
之前文章 Kubernetes入門實踐--部署運行Go項目
裏鏡像的 Dockerfile
長這樣:
FROM golang:1.14-alpine
RUN mkdir /app
COPY . /app
WORKDIR /app
RUN go build -o main .
CMD ["/app/main"]
我們使用多階段構建的方式構建鏡像後, Dockerfile
會變成類似下面這樣:
FROM golang:alpine AS build
RUN mkdir /app
COPY . /app
WORKDIR /app
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp
###
FROM scratch as final
COPY --from=build /app/myapp .
CMD ["/myapp"]
Go
項目應用的 Dockerfile
通常大概類似這樣,但是每個項目的細節可能有所不同。 FROM golang:alpine
指定了開始階段的基礎映像(其中包含Go工具和庫,用於構建程序), AS build
是給這個階段取名爲 build
。
golang:alpine
指定了 Go
基礎映像的 alpine
版本, alpine
是專門爲容器設計的小型 Linux
發行版。這個 Dockerfile
中使用了兩次 FROM
指令,第二條 FROM scratch
行,它告訴 Docker
從一個全新的,完全空的容器鏡像重新開始,然後將上個階段編譯好的程序複製到其中。這個纔是我們隨後將用於運行的 Go
應用程序的容器鏡像。
scratch
鏡像是 Docker
項目預定義的最小的鏡像。使用 scratch
鏡像可以節省大量空間,因爲我們實際上不需要 Go
工具或其他任何東西來運行我們的編譯好的程序,這可能也是 Go
在容器時代的一個優勢吧。
使用 scratch
鏡像製作的 Go
應用鏡像在運行時會有一個不識別時區的問題。這個也是我們最近項目往 Kubernetes
上遷移時遇到的第一個問題,不過還好經過 Google
和查看 Go
加載系統時區的源碼我幫新來的運維小哥哥找到了解決方法,具體怎麼解決的下期的文章再告訴大家。
:heart:愛心三連
1.看到這裏了就點個在看支持下吧,你的 「 在看 」 是我創作的動力。
2.關注公衆號 網管叨bi叨
, 「每週爲您分享原創技術文章」
!
3.特殊階段,帶好口罩,做好個人防護。
“在看轉發” 是最大的支持