作者:森南有鹿63N | 来源:互联网 | 2023-01-22 18:44
有一个选项FROM scratch
可供我使用它看起来像一个非常有吸引力的方式来构建我的Go容器.
我的问题是,为了可靠地运行Go二进制文件,我还需要添加任何内容才能运行二进制文件吗?Compiled Go二进制文件似乎至少在我的笔记本电脑上运行它.
我的目标是将图像大小保持在最低限度,以确保安全性和基础设施管理.在最佳情况下,我的容器将无法在构建阶段之外执行二进制文件或shell命令.
1> John Chadwic..:
临时图像不包含任何内容.没有文件.但实际上,这对您有利.事实证明,CGO_ENABLED=0
除了他们使用的东西之外,构建的二进制文件完全没有任何要求.有几点要记住:
有了CGO_ENABLED=0
,你不能使用任何C代码.其实不太难.
有了CGO_ENABLED=0
,您的应用将不会使用系统DNS解析器.我不认为它默认情况下是正确的,因为它是阻塞的并且Go的本机DNS解析器是非阻塞的.
您的应用可能取决于某些不存在的内容:
进行HTTPS调用的应用程序(如对其他服务,即Amazon S3或Stripe API)将需要ca-certs以确认HTTPS证书的真实性.这也必须随着时间的推移而更新.服务HTTPS内容不需要这样做.
需要时区感知的应用需要时区信息文件.
一个很好的替代方案FROM scratch
是FROM alpine
,它将包括一个基本的阿尔卑斯山图像 - 这是非常小的(我相信5 MiB)并且包含musl libc,它与Go兼容并允许您链接到C库以及无需设置即可编译CGO_ENABLED=0
.您还可以利用其tzinfo和ca-certs定期更新alpine的事实.
(值得注意的是,由于Docker的重复数据删除,Docker层的开销有点摊销,当然这取决于基础映像的更新频率.但是,它有助于推销使用相当小的Alpine图像的想法.)
您现在可能不需要tzinfo或ca-certs,但最好是安全而不是抱歉; 您可能会意外添加依赖项而不会意识到它会破坏您的构建.所以我建议使用alpine
你的基础.alpine:latest
应该没事.
额外奖励:如果您想在Docker中获得可重现的构建的优势,但是图像尺寸较小,您可以使用Docker 17.06+中提供的新Docker多阶段构建.
它有点像这样:
FROM golang:alpine
ADD . /go/src/github.com/some/gorepo # may need some go getting if you don't vendor
RUN go build -o /app github.com/some/gorepo
FROM scratch # or alpine
COPY --from=0 /app /app
ENTRYPOINT ["/app"]
(如果我犯了任何错误,我道歉,我正在记忆中输入.)
请注意,在使用FROM scratch
时必须使用exec形式ENTRYPOINT
,因为shell表单不起作用(它取决于Docker图像/bin/sh
,它不会.)这在Alpine中可以正常工作.