【问题标题】:Choosing Golang docker base image选择 Golang docker 基础镜像
【发布时间】:2017-10-31 05:44:42
【问题描述】:

golangalpine 的图像大小在 300Mb 左右变化。

使用golang 图像而不是普通的alpine 有什么优势?

【问题讨论】:

  • 如果创建static go binary,可以使用scratch
  • 还有golang:alpine
  • @Зелёный 是的,有golang:alpine,但它比基本alpine 多约200Mb。只想知道golang镜像有什么优势
  • 主要优势显然是go lang 工具(以及许多其他工具,例如gitbash),这些工具在普通的alpine docker 映像中不可用。 Here is a good thread about a small docker images。我认为您的问题在这里可能与 IMO 无关。

标签: docker go alpine


【解决方案1】:

为什么不scratchcenturylink

您可以构建一个静态的 go 二进制文件并将其复制到 docker 映像中。

docker 镜像的大小将等于二进制文件的大小。

假设你的go二进制文件名为ma​​in_go,这就是你需要的Dockerfile

FROM centurylink/ca-certs
ADD main_go /
CMD ["/main_go"]

请记住,scratchcenturylink 是空白图像,因此您必须使用内置的所有库静态编译您的应用程序。

例子:

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main_go .

Here 你可以找到一些关于 docker、go and scratch 的额外信息,here 你可以找到一些关于 GOOS 值的信息。

更新:使用 alpine 构建映像的多阶段构建。

ARG GO_VERSION=1.15.6
 
# STAGE 1: building the executable
FROM golang:${GO_VERSION}-alpine AS build
RUN apk add --no-cache git
RUN apk --no-cache add ca-certificates
 
# add a user here because addgroup and adduser are not available in scratch
RUN addgroup -S myapp \
    && adduser -S -u 10000 -g myapp myapp
 
WORKDIR /src
COPY ./go.mod ./go.sum ./
RUN go mod download
 
COPY ./ ./
 
# Run tests
RUN CGO_ENABLED=0 go test -timeout 30s -v github.com/gbaeke/go-template/pkg/api
 
# Build the executable
RUN CGO_ENABLED=0 go build \
    -installsuffix 'static' \
    -o /app ./cmd/app
 
# STAGE 2: build the container to run
FROM scratch AS final
LABEL maintainer="gbaeke"
COPY --from=build /app /app
 
# copy ca certs
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
 
# copy users from builder (use from=0 for illustration purposes)
COPY --from=0 /etc/passwd /etc/passwd
 
USER myapp
 
ENTRYPOINT ["/app"]

更多信息可以在here找到。

【讨论】:

  • 请致电 scratchcenturylink/ca-certs。但是如果你 import "C" 或使用一个库,比如 C 库的包装器,你真的不能使用 scratch 吗?
  • 世纪链接回购不再维护,所以我建议编辑答案并删除对它的引用。
【解决方案2】:

简短回答:比较golang:alpinealpine 之间的差异会更公平。

在撰写本文时,golang 映像是基于 Debian 构建的,Debian 是与 Alpine 不同的发行版。 I'll quote the documentation from Docker Hub:

golang:<version>

这是事实上的图像。如果您不确定 您的需求是什么,您可能想使用这个。它被设计 既可用作一次性容器(安装源代码和 启动容器以启动您的应用程序),以及要构建的基础 其他图片。

golang:alpine

此图像基于流行的 Alpine Linux 项目, 可在 alpine 官方图片中找到。 Alpine Linux 要小得多 比大多数分发基础图像(~5MB),因此导致很多 总体而言,图像更窄。

当最终图像大小为 尽可能小。需要注意的主要警告是它确实 使用 musl libc 而不是 glibc 和朋友,所以某些软件可能 根据他们的 libc 要求的深度遇到问题。 但是,大多数软件都没有这个问题,所以这个 变体通常是一个非常安全的选择。看到这个黑客新闻评论 线程更多地讨论可能出现的问题和一些 使用基于 Alpine 的图像的优缺点比较。

总之,基于 Alpine 构建的镜像往往比 Debian 镜像小。但是,它们不会包含您可能会发现对开发和调试有用的各种系统工具。一个常见的折衷方案是使用golang 风格构建您的二进制文件,然后使用golang:alpinealpine 或上面评论中提到的scratch 部署到生产环境。

【讨论】:

  • 所以总而言之,最好在生产中使用alpine 图像并在开发和构建图像时使用golang;alpine
  • 是的,对于某些用例。如果您不介意使用最小的发行版,这将是一个很好的经验法则(Alpine 通常需要额外的配置才能使您的应用正常运行)。