0

我在skaffold开发一些 kubernetes 服务方面玩得很开心,但是我周期中最长的步骤之一是拉取容器的所有依赖项。

有没有人对我如何最好地缓存一个层中的所有依赖项有建议?在 docker 容器中构建 go 二进制文件是否有最佳实践?我应该有一个层来做一个go get吗?(我也是一个新手构建 go 二进制文件,还不知道所有的花里胡哨。)

4

4 回答 4

2

skaffold我在集成时遇到了完全相同的问题kubebuilder,完全解决这个问题的想法是:

  1. 安装 buildkit,例如brew install buildkit

  2. 要通过以下方式启用skaffold本地构建:

apiVersion: skaffold/v1beta9
kind: Config
build:
  local:
    useBuildkit: true
    useDockerCLI: true
...
  1. 编辑Dockerfile以启用它:
# syntax=docker/dockerfile:experimental

# Build the manager binary
FROM golang:1.12.5 as builder

...
# Build
#RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go
RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -o manager main.go
...

然后第一次它仍然会下载每个依赖项,但之后它将使用缓存,这大大加快了构建过程。

于 2020-12-06T14:36:05.317 回答
1

我同意格里高利·米哈尔金的观点。关于您的性能改进,我想命名基于moby/buildkit的Docker Build Enhancements。在撰写本文时,这些工具尚未正确记录,但通过一些试验和错误,您可能会找到您的解决方案。

使用 buildkit,您可以在RUN语句中使用缓存以减少后续执行的时间。他们也在他们的文档中提供了一个Go 的例子。为了让它工作,您必须为 Docker 守护程序和客户端启用实验性功能(在上面的链接中描述)。

于 2020-04-07T16:40:58.277 回答
1

我在谷歌上搜索了更多涵盖该过程的文章后发现了这篇文章:Using go mod download to speed up Golang Docker builds

该技巧的要点是将您的go.modgo.sum文件复制到容器中,然后运行go mod download以下载依赖项,然后在另一个步骤中继续您的构建。

这是有效的,因为除非您添加更多依赖项,否则您的go.modgo.sum文件不会更改。因此,当下RUN一条语句发生时,go mod downloaddocker 知道它可以缓存这一层。(来源

FROM golang:1.13.9-buster as builder

# Make Build dir
RUN mkdir /build
WORKDIR /build

# Copy golang dependency manifests
COPY go.mod .
COPY go.sum .

# Cache the downloaded dependency in the layer.
RUN go mod download

# add the source code
COPY . .
# Build
RUN go build -o app

# Run
FROM debian:buster-slim
COPY --from=builder /build
WORKDIR /app
CMD ["./app"]
于 2020-04-21T17:16:23.210 回答
0

Go 服务通常使用多阶段构建。因此,所有依赖项都已解决并且可执行文件都是在构建阶段构建的。最后阶段实际上是运行可执行文件。因此,您的最终图像尺寸会更小。虽然,它不会加快依赖解决阶段。

于 2020-04-07T15:49:33.177 回答