默认情况下,Docker 暂存包含哪些内容?



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

我的问题是运行二进制文件本身仍然有什么,我需要添加任何东西才能可靠地运行 Go 二进制文件吗?编译的 Go 二进制文件似乎至少在我的笔记本电脑上运行它。

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

暂存图像不包含任何内容。没有文件。但实际上,这可以对你有利。事实证明,用CGO_ENABLED=0构建的 Go 二进制文件除了它们使用的东西之外,绝对不需要任何东西。有几件事要记住:

使用
  • CGO_ENABLED=0,您不能使用任何 C 代码。其实不太难。
  • 使用
  • CGO_ENABLED=0,你的应用将不会使用系统 DNS 解析程序。无论如何,我认为它不会默认这样做,因为它是阻塞的,而 Go 的本机 DNS 解析器是非阻塞的。
  • 你的应用可能依赖于一些不存在的内容:
    • 进行 HTTPS 调用的应用程序(如对其他服务,即 Amazon S3 或 Stripe API(的调用将需要证书才能确认 HTTPS 证书的真实性。这也必须随着时间的推移而更新。提供 HTTPS 内容不需要这样做。
    • 需要时区感知的应用将需要时区信息文件。

FROM scratch的一个不错的替代品是FROM alpine,它将包括一个基本的阿尔卑斯山图像 - 它非常小(我相信是 5 MiB(,并且包括与 Go 兼容的 musl libc,并允许您链接到 C 库以及无需设置CGO_ENABLED=0即可编译。您还可以利用高山定期更新的事实,使用其 tzinfo 和 ca-certs。

(值得注意的是,由于Docker的重复数据删除,Docker层的开销被摊销了一些,当然,这被基础映像的更新频率所抵消。尽管如此,它仍然有助于推销使用相当小的阿尔卑斯山图像的想法。

你现在可能不需要 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,它不会。这将在阿尔卑斯山正常工作。

相关内容

最新更新