go服務docker實踐-縮小鏡像佔用

go服務docker實踐-縮小鏡像佔用

小張開始學習go語言啦,從服務發佈開始吧
背景: 需要發佈GO服務,所以開始編輯dockerfile,遇到了些問題,在此記錄下,一起學習吧,文檔同時更新到公衆號裏了,可以加個關注呦,寫的不對的地方請指出,3Q

在這裏插入圖片描述

1 說在前面

本文環境建立在已安裝docker服務基礎上,請先準備好docker環境

2 docker鏡像要求

我們首先思考一下雲原生對應用運行時的不同需求:

體積更小:對於微服務分佈式架構而言,更小的體積意味着更少的下載帶寬,更快的分發下載速度。

啓動速度更快:對於傳統單體應用,啓動速度與運行效率相比不是一個關鍵的指標。原因是,這些應用重啓和發佈頻率相對較低。然而對於需要快速迭代、水平擴展的微服務應用而言,更快的的啓動速度就意味着更高的交付效率,和更加快速的回滾。尤其當你需要發佈一個有數百個副本的應用時,緩慢的啓動速度就是時間殺手。對於Serverless 應用而言,端到端的冷啓動速度則更爲關鍵,即使底層容器技術可以實現百毫秒資源就緒,如果應用無法在 500ms 內完成啓動,用戶就會感知到訪問延遲。

佔用資源更少:運行時更低的資源佔用,意味着更高的部署密度和更低的計算成本。

(本次我們討論如何把體積縮小)

3 創建第一版dockerfile

在這個dockerfile中,我主要做了下面這幾件事

1 打包

爲了擺脫開發環境對打包的影響,我選擇了把打包過程放在了dockerfile中

2 啓動

在第一階段打包完成後,我們可以直接執行打包後的可執行文件

下面我們來看第一版dockerfile

    FROM golang
    MAINTAINER  天南
    WORKDIR /go/src/git.liebaopay.com/cm/cm_ad_free
    COPY . .
    RUN go build main.go
    EXPOSE 20020 20021 20022
    CMD ["./main","./config_local.ini",":20020",":20021",":20022"]

下面我們一步一步解析此dockerfile:

    # 我們以官方golang鏡像爲基礎鏡像,官方golang的gopath默認在 /go/src中,所以可以直接把我們的項目放在此# # gopath中
    FROM golang
    # 指定維護者名稱
    MAINTAINER  天南
    # 指定容器內的工作目錄,不存在目錄會自動創建
    WORKDIR /go/src/git.liebaopay.com/cm/cm_ad_free
    # 把dockerfile當前目錄下的所有目錄和文件都複製到上步指定的工作目錄下
    COPY . .
    # 開始打包
    RUN go build main.go
    # 暴露服務端口
    EXPOSE 20020 20021 20022
    # 使用cmd執行命令,這個命令映射到容器內部的命令爲  ./main ./config_local.ini :20020 :20021 :20022
    CMD ["./main","./config_local.ini",":20020",":20021",":20022"]

構建鏡像,並啓動

    docker build -t cm_ad_free_img_v1 .

構建個鏡像,指定tag名稱爲 cm_ad_free_img_v1

下圖可以看到,鏡像構建過程

在這裏插入圖片描述

鏡像構建成功後,我們進行啓動一個容器服務

    docker run --name cm_ad_free_container_v1  -it  -p 9988:20022 cm_ad_free_img_v1

下面說下參數信息

--name 指定容器名稱

-t 讓docker分配一個僞終端並綁定到容器的標準輸入上

-i 則讓容器的標準輸入保持打開 

-d 會採用後臺進行

-p 爲端口映射,宿主機端口:容器端口

檢查下生成的docker鏡像
在這裏插入圖片描述

我哩個去! 這鏡像佔用也太大了,足足佔用了890Mb,原因是什麼呢? 原來我們在構建鏡像的時候,引入的golang基礎鏡像以及做了不少操作,在操作的過程中,產生了不少臨時文件,這些臨時文件在運行時是不需要的

4 鏡像瘦身

Docker 提供了 Multi-stage Build(多階段構建),可以實現鏡像瘦身。

我們把dockerfile構建過程可以簡單分爲兩個階段,

第一個階段是生成可執行文件階段,使用了golang的基礎鏡像,並做了go build操作
第二個階段是執行可執行文件階段,其實第二個階段用到了第一階段的執行文件和基礎配置,執行過程中並不再依賴golang基礎鏡像
所以我們在最終發佈的鏡像中,只包含運行程序必要的文件和配置,不包含任何編譯時的依賴,這樣就減少了鏡像的體積

我們來看第二版的dockerfile,只對增加命令進行註釋

    # 引入golang作爲基礎命令並起別名爲 build
    FROM golang as build
    MAINTAINER  天南
    WORKDIR /go/src/git.liebaopay.com/cm/cm_ad_free
    COPY . .
    RUN go build main.go
    # 引入alphine最小linux鏡像
    FROM alpine
    # 設置工作目錄
    WORKDIR /data/app
    # 複製生成的可執行命令和一些配置文件
    COPY --from=build /go/src/git.liebaopay.com/cm/cm_ad_free/main .
    COPY --from=build /go/src/git.liebaopay.com/cm/cm_ad_free/config_local.ini .
    COPY --from=build /go/src/git.liebaopay.com/cm/cm_ad_free/logformat_local.xml .
    # !!! 注意,經測試發現alpine中缺少動態庫,經查詢後的解決方式爲創建一個軟鏈
    RUN  mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
    EXPOSE 20020 20021 20022
    CMD ["./main","./config_local.ini",":20020",":20021",":20022"]

構建鏡像後,查看下佔用磁盤,直接減少到26Mb,看來胖子變爲瘦子了,哈哈

在這裏插入圖片描述
創建容器,成功啓動服務,可以開心玩耍了 ~

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章