Docker的默认包含哪些内容?

有一个选项, FROM scratch使用它看起来像一个非常有吸引力的build设我的Go容器的方式。

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

我的目标是保持图像的大小为了安全和基于pipe理的原因。 在最佳情况下,我的容器将不能在构build阶段之外执行二进制文件或shell命令。

划痕图像不包含任何内容。 没有文件。 但实际上,这可以对你有利。 事实certificate,使用CGO_ENABLED=0构build的Go二进制文件除了使用什么之外,完全不需要任何东西。 有几件事要牢记:

  • CGO_ENABLED=0 ,不能使用任何C代码。 其实不太难。
  • CGO_ENABLED=0 ,你的应用程序将不使用系统DNSparsing器。 我不认为它默认情况下,因为它是阻止和Go的本地DNSparsing器是非阻塞的。
  • 你的应用程序可能取决于一些不存在的东西:
    • 使用HTTPS调用的应用程序(例如,在其他服务中,例如Amazon S3或Stripe API)将需要ca-certs以确认HTTPS证书的真实性。 这也必须随着时间的推移而更新。 这不是服务HTTPS内容所必需的。
    • 需要时区知识的应用程序将需要时区信息文件。

FROM scratch一个不错的select是FROM alpine ,这将包括一个基本的高山图像 – 这是非常微小的(我相信5 MiB),包括musl libc,它与Go兼容,并允许您链接到C库以及编译时不需要设置CGO_ENABLED=0 。 您还可以利用alpine定期更新的事实,使用它的tzinfo和ca-certs。

(值得注意的是,由于Docker的重复数据删除技术,Docker层的开销已经有了一定程度的缓解,尽pipe当然这会被你的基本映像更新的频率所抵消),但是它有助于推销使用相当小的Alpine映像的想法。

你现在可能不需要tzinfo或者ca-certs,但是最好是安全而不是抱歉; 你可以不小心添加一个依赖,而不会意识到它打破了你的构build。 所以我build议使用alpine作为你的基地。 alpine:latest应该没事的。

奖励:如果您希望Docker内部具有可重复构build的优点,但是使用较小的映像大小,则可以使用Docker 17.06+中提供的新Docker多阶段构build。

它有点像这样:

 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"] 

(我道歉,如果我犯了什么错误,我从记忆中input。)

请注意,在使用FROM scratch您必须使用ENTRYPOINT的EXEC表单,因为shell表单将无法工作(这取决于具有/bin/sh的Docker映像,而不是这样做)。这在Alpine中可以正常工作。