对我来说,有一个选项可以使用FROM scratch
,它看起来像是一个非常有吸引力的构建Go容器的方法。默认情况下,Docker scratch包含哪些内容?
我的问题是,它仍然有本地运行二进制文件,我需要添加任何东西,以便可靠地运行Go二进制文件?编译Go二进制似乎至少在我的笔记本电脑上运行它。
我的目标是为了安全和基础管理的原因保持图像尺寸最小。在最佳情况下,我的容器将无法在构建阶段之外执行二进制文件或shell命令。
对我来说,有一个选项可以使用FROM scratch
,它看起来像是一个非常有吸引力的构建Go容器的方法。默认情况下,Docker scratch包含哪些内容?
我的问题是,它仍然有本地运行二进制文件,我需要添加任何东西,以便可靠地运行Go二进制文件?编译Go二进制似乎至少在我的笔记本电脑上运行它。
我的目标是为了安全和基础管理的原因保持图像尺寸最小。在最佳情况下,我的容器将无法在构建阶段之外执行二进制文件或shell命令。
划痕图像不包含任何内容。没有文件。但实际上,这可以发挥你的优势。事实证明,使用CGO_ENABLED=0
构建的Go二进制文件除了要使用的内容外,完全不需要任何内容。有几件事要记住:
CGO_ENABLED=0
,你不能使用任何C代码。其实不太难。CGO_ENABLED=0
,您的应用程序不会使用系统DNS解析器。我认为它不会默认使用,因为它是阻塞的,Go的本地DNS解析器是非阻塞的。一个不错的选择,FROM scratch
是FROM 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
,泊坞窗图像上,它不会。)这将在阿尔卑斯正常工作。
非常感谢,约翰!很好的解释,特别是你对证书的暗示,我很确定我将来需要他们。 –