線上Go項目的Docker鏡像應該怎麼構建?

上期的文章:Kubernetes入門實踐--部署運行Go項目發佈後,有網友留言說我文章裏演示的鏡像是把項目文件和Go都打包到了鏡像裏,這樣鏡像的佔用空間會比較大。linux

Go開發的程序在編譯成二進制文件後是能夠在沒有安裝Go環境的系統裏執行的,若是隻把編譯完的二進制文件直接放到鏡像裏就能節省不少鏡像空間了。我給的回覆是文章的側重點是Kubernetes的實踐因此鏡像方面就沒有佔太多篇幅。golang

確實真實線上項目的應用鏡像通常都不像以前文章裏講那樣構建,由於生產項目各方面要求更嚴格些。鏡像構建的過程通常都是先用Docker容器把項目編譯成二進制文件,而後把編譯好的文件拷貝到一個新的容器鏡像裏,新鏡像裏通常只包含Linux系統運行須要的最基本的文件,不須要有Go環境,所以能減小不少佔用空間。整個這個過程都發生在鏡像構建的過程當中,這樣就能保證多環境的一致性,上面這個構建Docker鏡像的方式叫作多階段構建(multi stage build)。docker

多階段構建是17.05版本纔有的功能,因此使用前要先肯定下使用的Docker Engine的版本。bash

下面就來介紹一下怎麼使用Docker的多階段構建制做Go應用的鏡像。app

以前文章裏鏡像的Dockerfile長這樣:工具

FROM golang:1.14-alpine
RUN mkdir /app COPY . /app WORKDIR /app RUN go build -o main . CMD ["/app/main"] 複製代碼

咱們使用用多階段構建的方式構建鏡像後,Dockerfile會變成相似下面這樣:ui

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是給這個階段取名爲buildspa

golang:alpine指定了Go基礎映像的alpine版本, alpine是專門爲容器設計的小型Linux發行版。這個Dockerfile中使用了兩次FROM指令,第二條FROM scratch行,它告訴Docker從一個全新的,徹底空的容器鏡像從新開始,而後將上個階段編譯好的程序複製到其中。這個纔是咱們隨後將用於運行的Go應用程序的容器鏡像。設計

scratch鏡像是Docker項目預約義的最小的鏡像。 Docker用於Go程序的多階段構建很常見,使用scratch鏡像能夠節省大量空間,由於咱們實際上不須要Go工具或其餘任何東西來運行咱們的編譯好的程序,這可能也是Go在容器時代的一個優點吧。code

使用scratch鏡像製做的Go應用鏡像在運行時會有一個不識別時區的問題,這個也是咱們最近項目往Kubernetes上遷移時遇到的第一個問題,不過還好通過Google和查看Go加載時區的源碼找到了解決方法,具體怎麼解決的下期的文章再告訴你們。

相關文章
相關標籤/搜索