【问题标题】:Using 2 Dockerfiles in Cloud Build to re-use intermediary step image if CloudBuild fails如果 CloudBuild 失败,则在 Cloud Build 中使用 2 个 Dockerfile 来重用中间步骤映像
【发布时间】:2021-10-25 22:15:40
【问题描述】:

Cloud Build 因超时错误而失败(我正在尝试使用 Prophet 部署 CloudRun)。因此,我试图将 Dockerfile 一分为二(将图像保存在两者之间,以防万一失败)。我会像这样拆分 Dockerfile:

  • Dockerfile_one:python + 先知的依赖关系
  • Dockerfile_two:image_from_Dockerfile_one + 先知 + 其他依赖项

cloudbuild.yaml 应该是什么样子:

  1. 如果有以前可用的映像跳过该步骤,否则使用 Dockerfile_one 运行该步骤并保存映像
  2. 使用步骤(1)中的镜像,添加更多依赖并保存镜像以进行部署

这是 cloudbuild.yaml 现在的样子

steps:
#  create gcr source directory
- name: 'bash'
  args:
    - '-c'
    - |
      echo 'Creating gcr_source directory for ${_GCR_NAME}'
      mkdir _gcr_source
      cp -r cloudruns/${_GCR_NAME}/. _gcr_source

# Build the container image
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/${_GCR_NAME}', '.']
  dir: '_gcr_source'

# Push the container image to Container Registry
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/$PROJECT_ID/${_GCR_NAME}']

# Deploy container image to Cloud Run
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: gcloud
  args:
  - run
  - deploy
  - ${_GCR_NAME}
  - --image=gcr.io/$PROJECT_ID/${_GCR_NAME}

非常感谢!

【问题讨论】:

  • 一个更好的设计是保持简单。拥有一个构建基础映像的管道,您可以在需要时运行该管道。另一个使用此基础映像并完成其工作的管道。关注点分离总是更好、更简单、更智能。
  • 有道理。我了解如何在第一个管道中保存构建映像。如何从第二个图像中构建?
  • 如果您的构建镜像与此名称相同(例如在容器注册表中)gcr.io/projectid/baseimage,只需使用相同的镜像FROM gcr.io/projectid/baseimage 启动您的Dockerfile
  • @guillaumeblaquiere 谢谢!这就是我所需要的。我不知道我可以在 FROM 中指定 gcr.io/* 图像。我设法将构建拆分为两个 Dockerfile。在 Python 3.9 上它无论如何都不起作用。看起来 pystan 不适合 Python3.9。在 python3.8 上,即使使用 1 个 Dockerfile 也一切正常,但归根结底,这是一个很好的学习练习。
  • @guillaumeblaquiere 请发表您的评论作为答案,我会接受。

标签: dockerfile google-cloud-build cloudbuild.yaml


【解决方案1】:

不是答案,而是一种解决方法。如果有人有同样的问题,使用 Python3.8 而不是 3.9 对 Cloud Build 有效。

这就是 Dockerfile 的样子:

RUN pip install --upgrade pip wheel setuptools

# Install pystan
RUN pip install Cython>=0.22
RUN pip install numpy>=1.7
RUN pip install pystan==2.19.1.1

# Install other prophet dependencies
RUN pip install -r requirements.txt
RUN pip install prophet

虽然弄清楚如何为 CloudRun 迭代构建图像,但真的很棒。

【讨论】:

    【解决方案2】:

    为什么您的 Cloud Build 会因超时错误而失败?

    在 docker 中构建图像时,减小图像大小很重要。通常会创建多个 dockerfile 来处理图像大小限制。在您的情况下,您无法减小图像大小并仅包含所需的内容。

    有什么办法可以改正?

    • 根据这个documentation,多阶段构建,(在 Docker 17.05) 允许您在第一次“构建”中构建您的应用程序 容器并在另一个容器中使用结果,同时使用 相同的 Dockerfile。
    • 您在 Dockerfile 中使用了多个 FROM 语句。每个 FROM 指令可以使用不同的基础,并且每个指令都开始一个新的 构建阶段。您可以选择性地从一个阶段复制工件 给另一个人,在决赛中留下你不想要的一切 图片。要展示它是如何工作的,请关注link。
    • 您只需要一个 Dockerfile。
    • 结果是与以前相同的微小生产图像,带有一个 显着降低复杂性。你不需要创建任何 中间图像,您不需要提取任何伪影到 您的本地系统。

    它是如何工作的?

    • 您可以name your build stages。默认情况下,阶段不是 命名,并通过它们的整数来引用它们,从 0 开始 对于第一个 FROM 指令。但是,您可以通过以下方式命名您的阶段 在 FROM 指令中添加一个 AS。
    • 构建映像时,不一定需要构建 整个 Dockerfile 包括每个阶段。您可以指定target build stage。
    • 使用多阶段构建时,您不仅限于从 您之前在 Dockerfile 中创建的阶段。您可以使用 复制——从指令到copy from a separate image,或者 使用本地镜像名称、本地或 Docker 上可用的标签 注册表或标签 ID。
    • 您可以通过引用pick up where a previous stage离开 使用 FROM 指令时对其进行处理。
    • Google documentation中有一个dockerfile的例子 它使用多阶段构建。 hello 二进制文件首先内置 容器并注入第二个容器。因为第二个容器 基于scratch,生成的图像只包含你好 二进制文件,而不是过程中所需的源文件和目标文件 构建。
    FROM golang:1.10 as builder
    
    WORKDIR /tmp/go
    COPY hello.go ./
    RUN CGO_ENABLED=0 go build -a -ldflags '-s' -o hello
    
    FROM scratch
    CMD [ "/hello" ]
    COPY --from=builder /tmp/go/hello /hello
    
    • 这里是 tutorial,用于了解多阶段构建的工作原理。

    【讨论】:

      【解决方案3】:

      你需要有 2 个管道

      1. 第一个创建基本映像。像这样,您可以在每次需要重建此基础映像时触发它,其生命周期可能与您的应用程序生命周期不同。类似的东西
      steps:
      - name: 'gcr.io/cloud-builders/docker'
        args: ['build', '-t', 'gcr.io/<PROJECT_ID>/base-image', '-f', 'DOCKERFILE_ONE', '.']
      images: ['gcr.io/<PROJECT_ID>/base-image']
      
      1. 然后,在您的第二个 dockerfile 中,从基础映像开始,并使用第二个 Cloud Build 管道来构建、推送和部署它(就像您在问题的最后 3 个步骤中所做的那样)
      FROM gcr.io/<PROJECT_ID>/base-image
      COPY .....
      ....
      ...
      

      【讨论】:

      • 谢谢!我终于设法做到了,构建时间减少了 x5
      • 对于任何来到这里的人来说,使用 pystan 的 CloudBuild Python3.9 似乎并不顺利。看起来 pystan==2.19.1.1 仅在使用 GCB 构建时才能与 Python3.8 一起使用
      猜你喜欢
      • 2021-05-14
      • 2020-11-28
      • 2021-04-10
      • 2021-08-19
      • 1970-01-01
      • 2020-05-07
      • 2019-05-23
      • 1970-01-01
      • 2022-10-17
      相关资源
      最近更新 更多