婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 構建Golang應用最小Docker鏡像的實現

構建Golang應用最小Docker鏡像的實現

熱門標簽:廣東語音外呼系統供應商 地圖標注測試 濮陽自動外呼系統代理 澳門防封電銷卡 長沙ai機器人電銷 賺地圖標注的錢犯法嗎 福州鐵通自動外呼系統 智能電銷機器人營銷 烏魯木齊人工電銷機器人系統

我通常使用docker運行我的 golang 程序,在這里分享一下我構建 docker 鏡像的經驗。我構建 docker 鏡像不僅優化構建后的體積,還要優化構建速度。

示例應用

首先貼出代碼例子,我們假設要構建一個 http 服務

package main

import (
 "fmt"
 "net/http"
 "time"

 "github.com/gin-gonic/gin"
)

func main() {
 fmt.Println("Server Ready")
 router := gin.Default()
 router.GET("/", func(c *gin.Context) {
 c.String(200, "hello world, this time is: "+time.Now().Format(time.RFC1123Z))
 })
 router.GET("/github", func(c *gin.Context) {
 _, err := http.Get("https://api.github.com/")
 if err != nil {
  c.String(500, err.Error())
  return
 }
 c.String(200, "access github api ok")
 })

 if err := router.Run(":9900"); err != nil {
 panic(err)
 }
}

說明:

  • 這里選擇 Gin 作為例子,是為了演示我們有第三方包條件下要優化構建速度
  • main函數第一行打印了一行字,為了演示后面啟動時遇到的一個坑
  • 跟路由打印了時間,為了演示后面遇到的關于時區的坑
  • 路由 github 嘗試訪問 https://api.github.com,為了演示后面遇到的證書坑

這里我們可以先試一試構建后包的體積

$ go build -o server
$ ls -alh | grep server
-rwxrwxrwx 1 eyas eyas 14.6M May 29 10:26 server

14.6MB,這是一個http服務的 hello world,當然這是因為使用了 gin ,所以有些大,如果用標準包 net/http 寫的 hello world,體積大概是接近 7 MB

Dockerfile 的進化

版本一,初步優化

先看看第一個版本

FROM golang:1.14-alpine as builder
WORKDIR /usr/src/app
ENV GOPROXY=https://goproxy.cn
COPY ./go.mod ./
COPY ./go.sum ./
RUN go mod download
COPY . .
RUN go build -ldflags "-s -w" -o server

FROM scratch as runner
COPY --from=builder /usr/src/app/server /opt/app/
CMD ["/opt/app/server"]

說明:

  • 選擇 golang:1.14-alpine 作為編譯環境,是因為這是體積最小的golang編譯環境
  • 設置 GOPROXY 是為了提升構建速度
  • 先復制 go.mod 和 go.sum ,然后 go mod download,是為了防止每次構建都會重新下載依賴包,利用docker構建緩存提升構建速度
  • go build 時加上 -ldflags "-s -w" 去除構建包的調試信息,減小go構建后程序體積,大概能減小 1/4 吧
  • 使用了多階段構建,也就是 FROM XXX as xxx ,在構建程序包的時候,使用帶編譯環境的鏡像去構建,運行的時候其實完全不需要go的編譯環境,所以在運行階段使用docker的空鏡像 scratch 去運行。這部是減小鏡像體積最有效的方法了。

好了,下面開始構建鏡像

$ docker build -t server .
...
Successfully built 8d3b91210721
Successfully tagged server:latest

到了這一步,構建成功,看看鏡像大小

$ docker images
server     latest     8d3b91210721   1 minutes ago    11MB

11MB,還行,現在運行一下

$ docker run -p 9900:9900 server
standard_init_linux.go:211: exec user process caused "no such file or directory"

發現啟動報錯了,而且main函數的第一行打印語句都沒有出現,所以整個程序完全沒有運行。錯誤原因是缺少庫依賴文件。這其實是構建的 go 程序還依賴底層的 so 庫文件,不信可以在物理機編譯后看看它的依賴

$ go build -o server
$ ldd server
    linux-vdso.so.1 (0x00007ffcfb775000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9a8dc47000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9a8d856000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f9a8de66000)

這是不是跟我們的認知有點出入呢,說好無依賴的呢,結果還是有幾個依賴庫文件呢,雖然這幾個依賴都是最底層的,一般操作系統都會有,可誰叫我們選了 scratch,這個鏡像里面除了linux內核以外真的什么都沒了。

這是因為go build 是默認啟用 CGO 的,不信你可以試試這個命令 go env CGO_ENABLED,在 CGO 開啟情況下,無論代碼有沒有用CGO,都會有庫依賴文件,解決方法也很簡單,手動指定關閉CGO就行,而且包體積并不會增加哦,還會減少呢

$ CGO_ENABLED=0 go build -o server
$ ldd server
    not a dynamic executable

版本二,解決運行時報錯

FROM golang:1.14-alpine as builder
WORKDIR /usr/src/app
ENV GOPROXY=https://goproxy.cn
COPY ./go.mod ./
COPY ./go.sum ./
RUN go mod download
COPY . .
-RUN go build -ldflags "-s -w" -o server
+RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o server

FROM scratch as runner
COPY --from=builder /usr/src/app/server /opt/app/
CMD ["/opt/app/server"]

改動點: go build 前加了 CGO_ENABLED=0

$ docker build -t server .
...
Successfully built a81385160e25
Successfully tagged server:latest
$ docker run -p 9900:9900 server
[GIN-debug] GET  /             --> main.main.func1 (3 handlers)
[GIN-debug] GET  /github          --> main.main.func2 (3 handlers)
[GIN-debug] Listening and serving HTTP on :9900

正常啟動了,我們訪問一下試試,訪問之前看看當前時間

$ date
Fri May 29 13:11:28 CST 2020

$ curl http://localhost:9900    
hello world, this time is: Fri, 29 May 2020 05:18:28 +0000

$ curl http://localhost:9900/github
Get "https://api.github.com/": x509: certificate signed by unknown authority

發現有問題

  • 當前系統時間是 13:11:28 ,但是根據由顯示的時間是 05:11:53,其實是docker 容器內的時區不對,默認是 0 時區,可是我們國家是 東8區
  • 嘗試訪問 https://api.github.com/ 這是 https 站點,報證書錯誤

解決問題

  • 在容器放置根證書
  • 設置容器時區

版本三,解決運行環境時區與證書問題

FROM golang:1.14-alpine as builder
WORKDIR /usr/src/app
ENV GOPROXY=https://goproxy.cn
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories  \

+ apk add --no-cache ca-certificates tzdata
COPY ./go.mod ./
COPY ./go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o server

FROM scratch as runner
+COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /usr/src/app/server /opt/app/
CMD ["/opt/app/server"]

在 builder 階段,安裝了 ca-certificates tzdata 兩個庫,在runner階段,將時區配置和根證書復制了一份

$ docker build -t server .
...
Successfully built e0825838043d
Successfully tagged server:latest
$ docker run -p 9900:9900 server
[GIN-debug] GET  /             --> main.main.func1 (3 handlers)
[GIN-debug] GET  /github          --> main.main.func2 (3 handlers)
[GIN-debug] Listening and serving HTTP on :9900

訪問一下試試

$ date
Fri May 29 13:27:16 CST 2020

$ curl http://localhost:9900    
hello world, this time is: Fri, 29 May 2020 13:27:16 +0800

$ curl http://localhost:9900/github
access github api ok

一切正常了,看看當前鏡像大小

$ docker images
server     latest     e0825838043d   9 minutes ago    11.3MB

才 11.3MB,已經很小了,但是,還可以更小,就是把構建后的包再壓縮一次

版本四,進一步減小體積

FROM golang:1.14-alpine as builder
WORKDIR /usr/src/app
ENV GOPROXY=https://goproxy.cn
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories  \

- apk add --no-cache ca-certificates tzdata
+ apk add --no-cache upx ca-certificates tzdata
COPY ./go.mod ./
COPY ./go.sum ./
RUN go mod download
COPY . .
-RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o server
+RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o server \

+ upx --best server -o _upx_server  \

+ mv -f _upx_server server

FROM scratch as runner
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /usr/src/app/server /opt/app/
CMD ["/opt/app/server"]

在 builder 階段,安裝了 upx ,并且go build 完成后,使用 upx 壓縮了一下,執行一下構建,你會發現這個構建時間變長了,這是因為我給 upx 設置的參數是 --best ,也就是最大壓縮級別,這樣壓縮出來的后會盡可能的小,如果嫌慢,可以降低壓縮級別從 -1 到 -9 ,數字越大壓縮級別越高,也越慢。我使用 --best 構建完成后看看鏡像體積。

$ docker build -t server .
...
Successfully built 80c3f3cde1f7
Successfully tagged server:latest
$ docker images
server     latest     80c3f3cde1f7   1 minutes ago    4.26MB

這下子可小了,才 4.26MB,再去試試那兩個接口,一切正常。優化到此結束。

最終的Dockerfile

FROM golang:1.14-alpine as builder
WORKDIR /usr/src/app
ENV GOPROXY=https://goproxy.cn
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories  \

 apk add --no-cache upx ca-certificates tzdata
COPY ./go.mod ./
COPY ./go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o server \

 upx --best server -o _upx_server  \

 mv -f _upx_server server

FROM scratch as runner
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /usr/src/app/server /opt/app/
CMD ["/opt/app/server"]

總結

要減小鏡像體積,首先多階段構建這很重要,這樣就可以把編譯環境和運行環境分開。

另外,選擇 scratch 這個鏡像其實很不明智,它雖然很小,但是它太原始了,里面什么工具都沒有,程序啟動后,連容器都進不去,就算進去了什么都做不了。所以就算一昧的追求盡可能小的鏡像體積,也不建議選擇 scratch 作為運行環境,我暫時只踩到小部分的坑,后面還有更多坑沒踩,我也沒有興趣繼續踩 scratch 的坑。

建議選擇 alpine ,alpine 的鏡像大小是 5.61MB 這個大小其實還是鏡像解壓后的大小,實際上下載鏡像的時候,只需要下載 2.68 MB 。還有,上文所有我說的鏡像體積,全都是指解壓后的鏡像體積,和實際上傳下載時的體積是不一樣的,docker自己會壓縮一次再傳輸鏡像

還有個很小的鏡像是 busybox,它的體積是 1.22MB,下載 705.6 KB ,有大部分的linux命令可用,但是運行環境還是很原始,有興趣可以去嘗試

無論是 alpine 還是 busybox ,他們都會上述時區和證書問題,同樣按照上面方法就能解決,切換到 alpine 或者 busybox 也很簡單,只需要修改 runner 基礎鏡像就行

-FROM scratch as runner
+FROM alpine as runner

或者

-FROM scratch as runner
+FROM busybox as runne

到此這篇關于構建Golang應用最小Docker鏡像的實現的文章就介紹到這了,更多相關Golang構建最小Docker鏡像內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 基于Docker鏡像部署go項目的方法步驟
  • Docker 部署Go的兩種基礎鏡像的實現

標簽:調研邀請 西雙版納 太原 廣西 阿克蘇 貴陽 德州 慶陽

巨人網絡通訊聲明:本文標題《構建Golang應用最小Docker鏡像的實現》,本文關鍵詞  構建,Golang,應用,最小,Docker,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《構建Golang應用最小Docker鏡像的實現》相關的同類信息!
  • 本頁收集關于構建Golang應用最小Docker鏡像的實現的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    精品国产免费一区二区三区四区| 日韩色视频在线观看| 亚洲国产精品一区二区www在线 | 国产精品理伦片| 欧美一区二区观看视频| 在线观看视频一区二区| 国产99久久久国产精品潘金网站| 日韩国产欧美在线播放| 久久国产精品72免费观看| 亚洲午夜一区二区| aa级大片欧美| 日韩av高清在线观看| 色悠悠亚洲一区二区| 久久网站热最新地址| 精品入口麻豆88视频| 懂色av一区二区三区免费看| 国产精品白丝jk黑袜喷水| 884aa四虎影成人精品一区| 欧美图区在线视频| 中文在线免费一区三区高中清不卡| 欧美大片一区二区| 午夜精品久久久久影视| 日本乱码高清不卡字幕| 欧美午夜精品电影| 亚洲欧洲av在线| 亚洲国产成人一区二区三区| 国产最新精品精品你懂的| 国产一区二区电影| 日韩欧美一区中文| 日韩有码一区二区三区| 久久精品国产秦先生| 欧美日韩高清不卡| 亚洲风情在线资源站| 日本视频在线一区| 欧美高清精品3d| 亚洲激情图片一区| 日韩av在线发布| 欧美日韩综合一区| 亚洲最大的成人av| 欧美性欧美巨大黑白大战| 欧美精品色一区二区三区| 国产精品日日摸夜夜摸av| 亚洲少妇30p| 成人福利视频在线看| 国产精品国产三级国产aⅴ原创| 从欧美一区二区三区| 国产自产视频一区二区三区| 久久精品亚洲乱码伦伦中文| www.成人在线| 成人午夜av电影| 国产精品国产馆在线真实露脸 | 在线观看不卡一区| 中文字幕一区二区三区四区不卡 | 日韩激情一二三区| 欧美精品v日韩精品v韩国精品v| 天堂成人国产精品一区| 成人黄动漫网站免费app| 自拍偷拍国产精品| 欧美午夜一区二区| 日本免费新一区视频 | 国产综合久久久久久久久久久久| 国产欧美一区在线| 99精品国产91久久久久久 | 成年人国产精品| 中文字幕亚洲在| 欧美性一区二区| 日韩精品欧美精品| 久久久综合九色合综国产精品| 欧美一区二区在线视频| 国产一区二区女| 亚洲私人影院在线观看| 亚洲激情图片小说视频| 色呦呦日韩精品| 国产精品中文字幕欧美| 亚洲第一成人在线| 国产精品乱码妇女bbbb| 日韩欧美一区在线观看| 欧美日韩夫妻久久| 不卡的av电影在线观看| 美女免费视频一区二区| 亚洲一区在线观看免费观看电影高清| 久久色.com| 欧美高清视频www夜色资源网| 激情亚洲综合在线| 一本大道综合伊人精品热热 | 婷婷综合久久一区二区三区| 亚洲一区二区美女| 久久日一线二线三线suv| 樱桃国产成人精品视频| 91久久精品一区二区| 一区二区三区在线看| 欧美高清视频一二三区| av在线一区二区三区| 亚洲永久免费视频| 国产精品久久久久久久久果冻传媒| 成人丝袜18视频在线观看| 亚洲欧美一区二区三区孕妇| 国产欧美va欧美不卡在线 | 奇米影视一区二区三区| 国产午夜精品久久| 欧美日韩国产在线播放网站| 成人99免费视频| 蜜臀久久99精品久久久久久9| 亚洲欧洲精品天堂一级 | 粉嫩高潮美女一区二区三区| 日本vs亚洲vs韩国一区三区二区 | 日韩av一级片| 一区二区三区电影在线播| 亚洲美女免费视频| 欧美精品一区二区三区很污很色的| 欧美一级一区二区| 欧美一级在线免费| 欧美精品一区二区三区在线播放| 欧美日韩精品高清| 日韩三级电影网址| 国产亚洲女人久久久久毛片| 国产丝袜美腿一区二区三区| 国产精品免费视频一区| 一区二区不卡在线播放 | 91色porny| 在线观看www91| 欧美剧情片在线观看| 欧美乱妇23p| 欧美国产精品中文字幕| 亚洲一区二区三区小说| 精品一区二区三区免费视频| 精品一区二区三区免费播放 | 亚洲男人天堂av| 亚洲国产wwwccc36天堂| 免费看黄色91| 国产成人亚洲综合色影视| 亚洲最大成人网4388xx| 亚洲成人午夜影院| 蜜臀av性久久久久蜜臀aⅴ| 免费在线一区观看| 国产精一区二区三区| 欧美体内she精视频| 久久久精品黄色| 一区二区三区日韩在线观看| 国产成人av一区| 欧美丰满美乳xxx高潮www| 亚洲欧洲国产日本综合| 狠狠色综合色综合网络| 欧美午夜免费电影| 亚洲免费视频成人| 成人高清视频在线观看| 精品一区二区在线看| 911精品产国品一二三产区| 国产精品伦理在线| 国产一区二区三区精品视频| 欧美无砖专区一中文字| 亚洲美女屁股眼交| 波多野结衣精品在线| 日本一区二区三区免费乱视频| 美腿丝袜一区二区三区| 欧美午夜免费电影| 亚洲福利一二三区| 亚洲欧美另类小说| 国产一区二区三区蝌蚪| 久久99国产精品免费| 精品粉嫩超白一线天av| 欧美日韩亚洲另类| 欧美亚洲另类激情小说| 亚洲精品国产一区二区精华液 | 亚洲午夜精品久久久久久久久| 日韩欧美一二三区| 亚洲国产美国国产综合一区二区| 成人av在线资源网| **性色生活片久久毛片| 91精品欧美久久久久久动漫| 亚洲成a人片综合在线| 亚洲欧美色综合| 日韩理论在线观看| 精品一二线国产| 亚洲一区二区四区蜜桃| 精品国偷自产国产一区| 国产在线视频不卡二| 欧美精品一区二区在线观看| 972aa.com艺术欧美| 亚洲va天堂va国产va久| 欧美本精品男人aⅴ天堂| 色综合视频一区二区三区高清| 免费看黄色91| 亚洲一区在线电影| 中文文精品字幕一区二区| 777奇米四色成人影色区| 91蝌蚪国产九色| 成人avav影音| 国内外精品视频| 午夜不卡在线视频| 亚洲激情第一区| 中文字幕一区二区三区不卡在线| 欧美xxx久久| 欧美电影在线免费观看| 国产一区二区h| 日韩在线a电影| 午夜视黄欧洲亚洲| 亚洲色欲色欲www| 国产日韩欧美综合一区| 欧美精品一区二区三区在线|