2017-08-16 46 views
2

对我来说,有一个选项可以使用FROM scratch,它看起来像是一个非常有吸引力的构建Go容器的方法。默认情况下,Docker scratch包含哪些内容?

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

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

回答

5

划痕图像不包含任何内容。没有文件。但实际上,这可以发挥你的优势。事实证明,使用CGO_ENABLED=0构建的Go二进制文件除了要使用的内容外,完全不需要任何内容​​。有几件事要记住:

  • CGO_ENABLED=0,你不能使用任何C代码。其实不太难。
  • 由于CGO_ENABLED=0,您的应用程序不会使用系统DNS解析器。我认为它不会默认使用,因为它是阻塞的,Go的本地DNS解析器是非阻塞的。
  • 您的应用程序可能会依赖于某些事情是不存在的:
    • 应用,使HTTPS调用(如,其他服务,如亚马逊S3,或条纹API)将需要CA-证书,以确认HTTPS证书的真实性。这也必须随着时间的推移而更新。这不是服务HTTPS内容所必需的。
    • 需要时区知晓的应用程序需要时区信息文件。

一个不错的选择,FROM scratchFROM alpine,其中将包括基本的阿尔卑斯山的形象 - 这是非常微小(5 MIB我相信),包括MUSL的libc,这与围棋兼容,并且可以让你链接到C库以及编译时不需要设置CGO_ENABLED=0。您还可以利用alpine定期更新的事实,使用它的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时必须使用的ENTRYPOINT的EXEC形式,因为壳的形式是不行的(这取决于有/bin/sh,泊坞窗图像上,它不会。)这将在阿尔卑斯正常工作。

+0

非常感谢,约翰!很好的解释,特别是你对证书的暗示,我很确定我将来需要他们。 –

相关问题