tft每日頭條

 > 生活

 > docker的加載運行和管理的過程

docker的加載運行和管理的過程

生活 更新时间:2024-11-13 07:07:51

docker的加載運行和管理的過程(如何将GoWeb)1

你或許想在 Docker 中使用 Go,原因有:

  1. 如果你想在 Kubernetes 上運行,打包為鏡像是必須的(就像我一樣)
  2. 你不得不在同一台機器上運行不同的 Go 版本
  3. 開發和生産都需要精确的、可複制的、可共享的和确定的環境
  4. 你需要快速和簡單的方式來構建和部署編譯好的二進制文件
  5. 你想快速開始(任何安裝了 Docker 的人都可以直接開始編寫代碼而不需要設置其他依賴或 GOPATH 環境變量)

恭喜你,你來對地方了。

我們将逐步構建一個基本的 dockerfile,包括實時重載包管理,然後進行擴展,創建一個高度優化的生産版的鏡像,其大小縮減了 100 倍。如果你使用 CI/CD 系統,鏡像大小可能無關緊要,但是當 docker push 和 docker pull 時,一個精簡的鏡像肯定會有幫助。

如果你隻想要最終的代碼,請看 GitHub

docker的加載運行和管理的過程(如何将GoWeb)2

假設我們的應用叫 go-docker,下面是項目的結構。所有的源碼都在 src 目錄下,Dockerfile 跟它在同一級目錄。 main.go 定義了一個 web-app 并監聽 8080 端口。

docker的加載運行和管理的過程(如何将GoWeb)3

最簡單的版本

docker的加載運行和管理的過程(如何将GoWeb)4

我們使用 debian jessie 版本的 golang 鏡像,因為像 go get 這樣的命令需要安裝有 git 等工具。對于生産版本,我們會用更加輕量的版本,如 alpine。

構建并運行該鏡像:

docker的加載運行和管理的過程(如何将GoWeb)5

成功後可以通過 http://localhost:8080 來訪問。按下 Ctrl C 可以中斷服務。

但這并沒有多大意義,因為每次修改代碼時,我們都必須構建和運行docker 鏡像。

一個更好的版本是将源代碼挂載到 docker 容器中,并使用容器内的 shell 來停止和啟動 go run。

docker的加載運行和管理的過程(如何将GoWeb)6

這個命令會提供一個 shell,我們可以在裡面執行 go run src/main.go 以啟動服務。我們可以在宿主機上編輯 main.go 并重新運行該命令來查看變化,因為現在源代碼已經直接挂載到了容器中。

但是,如何管理包呢?

包管理和鏡像分層

Go 的包管理 仍處在實驗階段。有很多工具可以選擇,但是我最喜歡的是 Glide。我們将在容器中安裝 Glide 并使用它。

在 go-docker 項目中新建兩個文件 glide.yaml 和 glide.lock:

docker的加載運行和管理的過程(如何将GoWeb)7

按照下面所示修改 Dockerfile 并構建一個新的鏡像:

docker的加載運行和管理的過程(如何将GoWeb)8

如果你觀察比較細緻,你會發現 glide.yaml 和 glide.lock 是分開添加的(并沒有用 ADD . .),這樣會導緻有單獨分離的層。将包管理分離為單獨的層,可以充分利用 Docker 層的緩存,并且隻有當對應的文件發生變化才會導緻重新編譯,比如:新增或删除了一個包。因此,glide install 不會在每次修改了代碼之後都去執行。

讓我們進入容器的 shell 安裝一個包:

docker的加載運行和管理的過程(如何将GoWeb)9

Glide 會将所有包安裝到 vendor 目錄,該目錄可以被 gitignored 和 dockerignored。使用 glide.lock 來鎖定某個包的版本。要安裝(或重新安裝)glide.yaml 中提到的所有包,執行:

docker的加載運行和管理的過程(如何将GoWeb)10

現在 go-docker 目錄有所增長:

docker的加載運行和管理的過程(如何将GoWeb)11

實時重載

codegangsta/gin 是我最喜歡的實時重載工具。它簡直就是為 Go web 服務而生的。我們使用 go get 來安裝 gin:

docker的加載運行和管理的過程(如何将GoWeb)12

構建鏡像并運行 gin 以便當我們修改了 src 中的源代碼時可以自動重新編譯:

docker的加載運行和管理的過程(如何将GoWeb)13

注意到 web-server 需要一個 PORT 的環境變量來監聽,因為 gin 會随機設置 PORT 變量并代理到該端口的連接。

現在,修改 src 目錄下的内容會觸發重新編譯,所有更新的内容可以實時在 http://localhost:8080 訪問到。

一旦開發完畢,我們可以構建二進制文件并運行它,而不需要使用 go run 命令。可以使用相同的鏡像來構建,或者也可以使用 Docker 的多階段構建,即使用 golang 鏡像來構建并使用迷你 linux 容器如 alpine 來運行服務。

單階段生産構建

docker的加載運行和管理的過程(如何将GoWeb)14

構建并運行該一體化的鏡像:

docker的加載運行和管理的過程(如何将GoWeb)15

因為底層使用了 Debian 鏡像,該鏡像會達到 750 MB 左右的大小(取決于你的源代碼)。讓我們看看如何縮減體積。

多階段生産構建

多階段構建允許你在一個完整的 OS 環境中進行構建,但構建後的二進制文件通過一個非常苗條的鏡像來運行,該鏡像僅比構建後的二進制文件略大一點而已。

docker的加載運行和管理的過程(如何将GoWeb)16

現在二進制文件為 14 MB 左右,docker 鏡像為 18 MB 左右。真是多虧了 alpine。

想減小二進制文件體積嗎?繼續看吧。

福利:使用 UPX 來壓縮二進制文件

Hasura,我們已經在到處使用 UPX 了,壓縮後我們的 CLI 二進制文件從 50 MB 左右降到 8 MB左右,大大加快了下載速度。UPX 可以極快地進行原地解壓,不需要額外的工具,因為它将解壓器嵌入到了二進制文件内部。

docker的加載運行和管理的過程(如何将GoWeb)17

UPX 壓縮後的二進制文件為 3 MB 左右并且 docker 鏡像為 6 MB 左右。

相比最開始的鏡像,縮減了 100 倍

如果你有更好的建議或是你需要其他的使用場景,請在評論區留言或者去 HackerNewsReddit 進行讨論。

額...你嘗試過在 Hasura 上部署 Go web-app 嗎?這真的是世界上最快的将 Go apps 部署到 HTTPS 域下的方法(僅僅 git push 就夠了)。使用這裡的項目模闆快速開始吧:https://hasura.io/hub/go-frameworks。Hasura 所有項目模闆都配套有 Dockerfile 和 Kubernetes spec,允許你按照你的方式來自定義。


via: https://blog.hasura.io/the-ultimate-guide-to-writing-dockerfiles-for-go-web-apps-336efad7012c

作者:Shahidh K Muhammed 譯者:ParadeTo 校對:polaris1119

本文由 GCTT 原創編譯,Go語言中文網 榮譽推出

docker的加載運行和管理的過程(如何将GoWeb)18

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved