Docker scratch默认包含什么?

时间:2017-08-16 20:50:39

标签: docker go dockerfile

有一个选项可以使用FROM scratch对我来说它看起来像是一个非常有吸引力的构建我的Go容器的方式。

我的问题是,为了可靠地运行Go二进制文件,我还需要添加任何内容才能运行二进制文件吗? Compiled Go二进制文件似乎至少在我的笔记本电脑上运行它。

我的目标是将图像大小保持在最低限度,以确保安全性和基础设施管理。在最佳情况下,我的容器将无法在构建阶段之外执行二进制文件或shell命令。

1 个答案:

答案 0 :(得分:9)

临时图像不包含任何内容。没有文件。但实际上,这对您有利。事实证明,使用CGO_ENABLED=0构建的Go二进制文件除了使用它们之外什么都不需要。有几点要记住:

  • 使用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时必须使用ENTRYPOINT的exec格式,因为shell格式不起作用(取决于具有/bin/sh的Docker镜像,它赢了是的。这在阿尔卑斯山很好用。