如何在Google云构建器中缓存多阶段docker build

nmi*_*nic 9 docker google-cloud-platform

我有docker多级构建,例如:

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]  
Run Code Online (Sandbox Code Playgroud)

比我有cloudbuild.yml:

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['pull', 'gcr.io/$PROJECT_ID/app:$BRANCH_NAME']
- name: 'gcr.io/cloud-builders/docker'
  args: ['pull', 'gcr.io/$PROJECT_ID/app:latest']
- name: 'gcr.io/cloud-builders/docker'
  args: [
            'build',
            '--cache-from', 'gcr.io/$PROJECT_ID/app:latest',
            '--cache-from', 'gcr.io/$PROJECT_ID/app:$BRANCH_NAME',
            '--build-arg', 'COMMIT_HASH=$COMMIT_SHA',
            '-t', 'gcr.io/$PROJECT_ID/app:$COMMIT_SHA',
            '-f', 'config/dockerfiles/app.dockerfile',
            '.'
        ]
- name: 'gcr.io/cloud-builders/docker'
  args: ["tag", "gcr.io/$PROJECT_ID/app:$COMMIT_SHA", "gcr.io/$PROJECT_ID/app:$BRANCH_NAME"]
- name: 'gcr.io/cloud-builders/docker'
  args: ["tag", "gcr.io/$PROJECT_ID/app:$COMMIT_SHA", "gcr.io/$PROJECT_ID/app:latest"]
images: [
  'gcr.io/$PROJECT_ID/app:$COMMIT_SHA',
  'gcr.io/$PROJECT_ID/app:$BRANCH_NAME',
  'gcr.io/$PROJECT_ID/app:latest'
]
Run Code Online (Sandbox Code Playgroud)

现在我想要不仅缓存生成的图像,还要缓存构建器步骤.例如,在go中我使用dep构建的/ vendor,并且想要缓存这些依赖项.我如何通过谷歌云平台取得最简单的成绩?我认为我的问题主要是码头工具,但仍然存在.

小智 6

构建器映像需要分别构建和标记。您需要从构建阶段推送该映像,并在下一个构建中将其用作缓存。为此,更方便地命名您的构建阶段。

FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
Run Code Online (Sandbox Code Playgroud)

在您中,cloudbuild.yaml您需要知道应该拉哪个图像来执行更好的缓存使用,并将该决定“存储”在某个地方。我将向您展示如何通过存储在文件中来完成此操作。

如果将逻辑放在一个构建步骤中会更容易:

steps:
- name: 'gcr.io/cloud-builders/docker'
  entrypoint: 'bash'
  args:
    - '-c'
    - |
      mkdir tmp
      (docker pull gcr.io/$PROJECT_ID/app:$BRANCH_NAME && echo "$BRANCH_NAME" > tmp/base) ||
        echo "master" > tmp/base

      docker pull "us.gcr.io/$PROJECT_ID/app-builder:$(cat tmp/base)" || true
      docker pull "us.gcr.io/$PROJECT_ID/app:$(cat tmp/base)" || true

      docker build \
          --cache-from "gcr.io/$PROJECT_ID/app-builder:$(cat tmp/base)" \
          -t us.gcr.io/$PROJECT_ID/app-builder:$BRANCH_NAME \
          -t us.gcr.io/$PROJECT_ID/app-builder:$COMMIT_SHA \
          -t us.gcr.io/$PROJECT_ID/app-builder:latest \
          --build-arg COMMIT_HASH=$COMMIT_SHA \
          -f config/dockerfiles/app.dockerfile \
          --target builder \
          .

      docker build \
          --cache-from "gcr.io/$PROJECT_ID/app-builder:$COMMIT_SHA" \
          --cache-from "gcr.io/$PROJECT_ID/app:$(cat tmp/base)" \
          -t us.gcr.io/$PROJECT_ID/app:$BRANCH_NAME \
          -t us.gcr.io/$PROJECT_ID/app:$COMMIT_SHA \
          -t us.gcr.io/$PROJECT_ID/app:latest \
          --build-arg COMMIT_HASH=$COMMIT_SHA \
          -f config/dockerfiles/app.dockerfile \
          .
images: [
  'gcr.io/$PROJECT_ID/app-builder:$COMMIT_SHA',
  'gcr.io/$PROJECT_ID/app-builder:$BRANCH_NAME',
  'gcr.io/$PROJECT_ID/app-builder:latest',
  'gcr.io/$PROJECT_ID/app:$COMMIT_SHA',
  'gcr.io/$PROJECT_ID/app:$BRANCH_NAME',
  'gcr.io/$PROJECT_ID/app:latest'
]
Run Code Online (Sandbox Code Playgroud)

该脚本在tag内部创建文件tmp/,因此Docker忽略此目录或文件(将其放在上.dockerignore)很重要。

请注意,我避免同时使用--cache-from两个图像。这是因为在我的实验中,由于构建使用的是最旧的映像作为缓存,因此我使缓存无效。还要注意,第一个docker build命令有一个--target参数。这是在告诉Docker仅在该阶段结束之前进行构建。

我将默认图像更改为,master因为它可以确保基本图像稳定,并且与您的分支没有太大差异,从而提高了性能。latest在我的示例中,该标签是不必要的。