週末期間,我對專門用於 Go (Golang) 應用程式的 docker 映像進行了一些研究。因此,我想分享這些有趣的發現,因為這可能對那些在技術專案中探索相同內容的人有用。
在這裡,我將詳細介紹幾種為 Golang 建立鏡像的不同方法,並強調我們在選擇一種方法時需要考慮的一些安全注意事項。
在本練習中,我使用了一個簡單的 Rest API,該 API 使用 Go (Golang) 和 Gin 框架開發。
Gin 框架 是一個流行的 Go (Golang) Web 框架,旨在快速、易於使用且高效。
以下是其主要功能和特性的簡要摘要;
主要特點
性能:琴酒以其高性能而聞名。它是最快的 Go Web 框架之一,與其他框架相比,提供了最小的開銷。
快速 HTTP 路由器:Gin 使用快速 HTTP 路由器,支援 GET、POST、PUT、DELETE 等方法的路由,也支援中間件和路由分組。
中間件支援:Gin 提供了一種使用中間件來處理日誌、驗證以及其他請求的預處理或後處理等任務的方法。
JSON 驗證: 該框架提供了對 JSON 驗證和將請求資料綁定到 Go 結構的內建支持,使使用 JSON 有效負載變得更容易。
錯誤處理:Gin 具有結構化的錯誤處理方式,並提供中央錯誤管理系統,讓您可以優雅地處理錯誤。
模板渲染:雖然 Gin 主要是為 API 開發而設計的,但如果需要,它也支援 HTML 模板渲染。
請求處理:支援不同的請求處理方法,包括表單資料、JSON 負載和 URL 參數。
內建偵錯:Gin 提供了在開發過程中有用的詳細錯誤訊息和偵錯資訊。
路由器:處理 HTTP 請求路由到適當處理程序的核心元件。
上下文: 承載請求和回應資料的結構,以及
提供了處理它們的方法。它在處理程序中廣泛使用。
引擎: Gin 應用程式的主實例,配置了路由、中間件和其他設定。
中間件:在請求生命週期中執行的函數,允許您執行日誌記錄、身份驗證等任務
關於 Gin 框架的介紹已經足夠了:)現在讓我們進入主題並討論所進行的測試。
在此測試中,我們將使用官方標準/常規 Go 基礎鏡像
# Official Go Base Image FROM golang:1.21.0 # Create The Application Working Directory WORKDIR /app # Copy and Download Dependencies COPY go.mod go.sum . RUN go mod download # Copy Source and Build The Application COPY . . RUN go build -o main . # Expose The Port EXPOSE 8081 CMD ["./main"]
影像尺寸
在此測試中,我們將使用稍微輕量級的 Go 基礎鏡像的 Alpine 版本
# Official Go Apline Base Image FROM golang:1.21.0-alpine as builder # Create The Application Directory WORKDIR /app # Copy and Download Dependencies COPY go.mod go.sum . RUN go mod download # Copy The Application Source & Build COPY . . RUN go build -o main . # Final Image Creation Stage FROM alpine:3.19 WORKDIR /root/ # Copy The Built Binary COPY --from=builder /app/main . # Expose the port EXPOSE 8081 CMD ["./main"]
影像尺寸
在這裡您可以看到,透過多階段構建,影像大小顯著減少。
在此測試中,我們將使用 Google 的 Distroless Go 基礎映像。 Distroless 映像以輕量級且安全而聞名,僅包含所需的最少檔案。在此,這些調試 shell 和不必要的套件被刪除。因此,您犧牲了套件管理器和 shell 的靈活性。
# Build Stage FROM golang:1.21.0 as builder # Set The Application Directory WORKDIR /app # Copy and Download Dependencies COPY go.mod go.sum . RUN go mod download # Copy The Application Source and Build the application COPY . . RUN CGO_ENABLED=0 go build -o main . # Final Image Creation Stage FROM gcr.io/distroless/static-debian12 # Copy the built binary COPY --from=builder /app/main / CMD ["/main"]
影像尺寸
CGO_ENABLED=0: 這是 CGO (C-Go) 停用的環境變數設定。 CGO 是 Go 的功能,允許 Go 套件呼叫 C 程式碼。設定 CGO_ENABLED=0 可確保建置不依賴任何 C 庫,從而產生完全靜態的二進位檔案。這對於創建可以在任何系統上運行而無需額外依賴項的輕量級和可移植的 Go 二進位檔案非常有用。
總而言之,RUN CGO_ENABLED=0 go build -o main . 意味著Docker 將執行命令在當前目錄中建立Go 應用程序,產生一個名為main 的靜態二進位文件,該二進位檔案不會依賴任何C 函式庫。
影像尺寸
儘管 Distroless 映像比 alpine 映像稍大,但出於安全威脅/漏洞考慮,可能會迫使您選擇 Distroless!。因此,請考慮所有這些事實並選擇符合您要求的一個
採用多階段構建的Alpine 如果您需要對構建過程進行更多控制,並且不存在與musl libc 的兼容性問題,那麼
Alpine 是個不錯的選擇一個擔憂。它提供了靈活性,並且比許多其他基礎映像更小,但仍包含比 Distroless 映像檔更多的元件,這可能會導致潛在的安全漏洞/威脅。
Google Distroless Images推薦: 如果您需要靈活性和對構建環境的控制,並且與 musl libc
的兼容性問題不是問題,請使用 Alpine。
如果安全性和最小化攻擊面是您的首要任務,請使用 Google Distroless,並且您可以確保您的應用程式正確地捆綁了所有依賴項。 希望這很有趣,謝謝您的寶貴時間!
以上是Go (Golang) 的 Docker 映像 更小、更快的 Docker 映像和安全性的詳細內容。更多資訊請關注PHP中文網其他相關文章!