周末期间,我对专门用于 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中文网其他相关文章!