选择Golang的Docker基础镜像

5

图像的大小golangalpine相差约300Mb

使用golang映像而不是纯粹的alpine有什么优点?


2
如果你创建一个静态 Go 二进制文件,你可以使用scratch - Matt
1
还有golang:alpine - Roman Kiselenko
@Зелёный 是的,有golang:alpine,但比基本的alpine多了约200Mb。只是想知道使用golang镜像的优势是什么。 - Shettyh
1
主要优势显然是go语言工具(以及许多其他工具,如gitbash),这些工具在普通的alpine docker镜像中不可用。这里有一个关于__小型__docker镜像的好帖子。我认为你的问题可能在这里不太相关。 - Roman Kiselenko
2个回答

6
简短回答:比较golang:alpinealpine之间的差异更加公平。
在撰写本文时,golang镜像基于Debian构建,这与Alpine不同。 我将引用来自Docker Hub的文档

golang:<version>

这是事实上的镜像。如果您不确定您的需求是什么,那么您可能想使用它。它旨在被用作可丢弃容器(挂载源代码并启动容器以启动应用程序),以及作为构建其他镜像的基础。


这个镜像基于流行的Alpine Linux项目,可在官方的alpine镜像中获得。相较于大多数发行版基础镜像(约5MB),Alpine Linux要小得多,因此通常会导致更为精简的镜像。如果希望最终镜像尽可能地小,则强烈推荐使用此变体。需要注意的主要是它使用musl libc而不是glibc和其他库,因此某些软件可能会因其libc要求的深度而遇到问题。但是,大多数软件都没有问题,因此这个变体通常是一个非常安全的选择。总之,使用Alpine构建的镜像往往比Debian的更小。但是,它们将不包含您可能发现用于开发和调试的各种系统工具。一种常见的折衷方案是使用golang版本构建二进制文件,并使用golang:alpinealpine或如上面的评论中提到的scratch部署到生产环境中。

总之,在生产环境中最好只使用 alpine 镜像,而在开发和构建镜像时使用 golang;alpine 镜像? - Shettyh
1
是的,对于某些用例来说是可以的。如果您不介意使用最小化的发行版(Alpine通常需要额外的配置才能使您的应用程序正常运行),那么这将是一个很好的经验法则。 - bosgood

6

为什么不选择 scratch

您可以构建一个静态的 Go 二进制文件,并将其复制到 Docker 镜像中。

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

假设您的 Go 二进制文件名为 main_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 .

这里有一些关于Docker、Go和Scratch的额外信息,点击这里查看;这里有一些关于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"]

More info can be found here.


1
关于 scratchcenturylink/ca-certs 的选择很好。但是如果你使用了 import "C" 或者使用了一个包装 C 库的库,那么你就不能真正使用 scratch 了吧? - Michael Hampton
2
世纪互联的代码库已经不再维护,因此我建议编辑答案并删除与之相关的引用。 - Gautam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接