如何在 google cloudbuild 上构建 quarkus 原生镜像

Posted

技术标签:

【中文标题】如何在 google cloudbuild 上构建 quarkus 原生镜像【英文标题】:How to build quarkus native image on google cloudbuild 【发布时间】:2021-06-13 05:46:45 【问题描述】:

有人知道如何在 cloudbuild 上构建 quarkus 原生镜像吗? 我使用以下命令:

- name: maven:3-jdk-11
    entrypoint: mvn
    args: ["package", "-Dmaven.test.skip=true", "-Pnative", "-Dquarkus.native.container-build=true", "-Dquarkus.container-image.build=true"]

本地一切正常,但是当我尝试在 Google Cloud 上执行此操作时,它会引发错误:

[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:1.12.2.Final:build (default) on project fishki: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR]     [error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: java.lang.IllegalStateException: No container runtime was found to run the native image builder
[ERROR]     at io.quarkus.deployment.pkg.steps.NativeImageBuildContainerRunner.detectContainerRuntime(NativeImageBuildContainerRunner.java:114)

我的想法是尝试提供容器运行时来运行本机映像生成器,但我不知道该怎么做。

我将不胜感激,谢谢!

编辑

我使用以下 cloudbuild.yaml

steps:
  - name: maven:3-jdk-11
    entrypoint: mvn
    args: ["quarkus:add-extension", "-Dextensions=container-image-docker"]
  - name: docker:latest
  - name: maven:3-jdk-11
    entrypoint: mvn
    args: ["package", "-Pnative", "-Dmaven.test.skip=true", "-Dquarkus.container-image.build=true", "-Dquarkus.native.container-build=true", "-Dquarkus.native.container-runtime=docker"]
  - name: 'gcr.io/cloud-builders/docker'
    args: [ 'build', '-t', 'gcr.io/XXX-XX-XXX/XX-XXX', '.' ]
  - name: "gcr.io/cloud-builders/docker"
    args: ["push", "gcr.io/XXXX/XXX-XXXX"]
  - name: "gcr.io/cloud-builders/gke-deploy"
    args:
      - run
      - --filename=./deployment.yaml
      - --image=gcr.io/XXX/XXX:latest
      - --location=europe-west1-b
      - --cluster=XX-XXX-XXX-1

现在我有一个新问题 - 当我尝试安装 docker 容器运行时,我收到以下错误:

[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:1.12.2.Final:build (default) on project fishki: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR]     [error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: java.lang.RuntimeException: Failed to pull builder image quay.io/quarkus/ubi-quarkus-native-image:21.0.0-java11

【问题讨论】:

【参考方案1】:

对于每个构建步骤,Cloud Build 都会执行一个 docker 容器作为 docker run 的实例。您的应用需要的是容器运行时本身。因此,您无法使用预构建的 Maven 构建器构建容器,因为映像不具备您的应用所需的要求。通过查看 Quarkus docs,您可以看到构建本机可执行文件需要 Docker 运行时。

更新:一种解决方案是创建您自己的custom builder,您可以在其中设置具有所有要求(JDK、Maven、Docker 等)的环境,然后在您的构建中使用它步骤而不是使用预制的构建器。

请参阅此说明如何build containers with a Dockerfile。

作为附加参考,这里是 Quarkus quickstart guide。

【讨论】:

我已经看过这些说明,但它们没有为我的问题提供答案(或者我错过了一些东西)。感谢您的帮助。 @Ksz 请看看我更新的答案是否可以帮助您找到正确的方向 感觉自己离成功又近了一步,但又遇到了新问题。好像我无法从 cloudbuild 环境中下载 docker-builder。【参考方案2】:

我为此苦苦挣扎了一段时间,但是您提出的问题中的信息对我有很大帮助,因此感谢您提供的想法使我解决了此问题。

我最终这样做的方式是像这样构建一个自定义构建映像 (Dockerfile):

FROM maven:3-jdk-11
run apt-get update
run apt-get install docker.io -y
run docker --version

您可以在此处找到我的构建映像(注意:我的构建映像适用于 gradle,而不是 maven): https://hub.docker.com/repository/docker/lackrobin/quarkus-gradle-build-image

将此图像推送到 gcr 或您可以从 google cloud build 访问的任何其他注册表。

cloudbuild.yaml 文件中,以下配置应该可以解决问题:

steps:
  - name: gcr.io/[link to the builder image above]
    args:
      - addExtension
      - '--extensions=container-image-docker'
      - build
      - '-Dquarkus.package.type=native'
      - '-Dquarkus.native.native-image-xmx=16g'
      - '-Dorg.gradle.jvmargs=-Xmx3g -XX:MaxPermSize=2048m'
    entrypoint: ./gradlew
  - name: gcr.io/cloud-builders/docker
    args:
      - build
      - '-t'
      - gcr.io/[project name]/[image name]
      - '-f'
      - src/main/docker/Dockerfile.native
      - .
images:
timeout: 2000s
  - gcr.io/gcr.io/[project name]/[image name]
options:
  machineType: E2_HIGHCPU_32

quarkus 或 GraalVM 使用大量资源来构建。我不得不使用具有更多资源的虚拟机进行构建。 options 下的命令 machineType: E2_HIGHCPU_32 负责。

【讨论】:

以上是关于如何在 google cloudbuild 上构建 quarkus 原生镜像的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud Build 不会替换 cloudbuild.yaml 的机密部分中的值

如何将自定义 Cloud Builders 与来自 Google Artifact Repository 的图像一起使用

Google Cloud Builder-构建触发器失败,并显示“未找到请求的资源”

如何在 cloudbuild.yaml 中使用 Kaniko?

Google Apps 脚本和 Cloudbuild CI 登录

Google Cloud 构建条件步骤