如何使用 jib-maven-plugin 解决从 Cloud Build 推送到 Google Artifact Registry 的权限问题?

How to solve permissions for push to Google Artifact Registry from Cloud Build using jib-maven-plugin?

这个问题似乎与我在 GCP 中的权限有关,但到目前为止尝试设置正确的权限并没有奏效。

我正在使用 com.google.cloud.tools:jib-maven-plugin 将 Spring 引导项目打包到容器中并将其推送到 Google Artifact Registry (GAR)。当我在本地 运行 它工作得很好,但是当我 运行 使用 Google Cloud Build 构建 Maven 时它失败了。它说它失败了,因为缺少 artifactregistry.repositories.downloadArtifacts 权限。

但这是根据 Google Docs 默认启用的权限之一。

我的目标是 Google 工件 (docker) 注册表。我可以将目标更改为 Google Container Registry(已弃用,因此我需要更改为 GAR)并且在 Cloud Build 下运行良好,没有权限问题。该构建还从存储在不同 GAR 中的 Maven 存储库下载 jar 文件,尽管在同一个 Google 项目中。很明显,该 Maven GAR 的权限是可以的。

我验证了 运行在本地构建 maven 是有效的,包括写入 GAR,这消除了 jib 插件配置或 GAR 配置中的问题。这是使用我自己的用户凭据。

我尝试了什么?

所有这些都给了我相同的权限被拒绝错误。以防万一我真的误解了一些东西,我在我的 Cloud Build yaml 中添加了一个步骤 运行s gcloud info 并验证了,是的,它正在使用我配置了我需要的角色的 BSA。

我错过了什么吗? 谢谢

...编辑 更多信息。我的大部分构建使用 jib,但有一个使用 Spotify 创建本地 docker 图像,然后使用 docker 推送到注册表。 这有效!所以问题是特定于 jib 的。不知何故,在云构建下,jib 看不到信用,尽管它确实在本地看到它们。

...编辑 实际错误信息:

Failed to execute goal com.google.cloud.tools:jib-maven-plugin:1.6.1:build (build-and-push-docker-image) on project knifethrower: Build image failed, perhaps you should make sure you have permissions for australia-southeast1-docker.pkg.dev/redacted/bonanza-platform/knifethrower and set correct credentials. See https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#what-should-i-do-when-the-registry-responds-with-forbidden-or-denied for help: Unauthorized for australia-southeast1-docker.pkg.dev/redacted/bonanza-platform/knifethrower: 403 Forbidden
[ERROR] {"errors":[{"code":"DENIED","message":"Permission \"artifactregistry.repositories.downloadArtifacts\" denied on resource \"projects/redacted/locations/australia-southeast1/repositories/bonanza-platform\" (or it may not exist)"}]}
[ERROR] -> [Help 1]

另请注意,我使用的是最新版本的 jib:3.1.4

...编辑

我已经尝试了更多的东西。我在 maven 构建之前添加了一个较早的步骤,它执行 gcloud auth configure-docker --quiet --verbosity=debug australia-southeast1-docker.pkg.dev。这会创建一个 /builder/home/.docker/config.json 文件。因为似乎对该文件应该存放在哪里感到困惑,所以我将其复制到 /root/.docker。但这并没有帮助。

我尝试的第二件事是使用 $DOCKER_CONFIG 指向 /builder/home/.docker 目录 (as suggested here),但这也没有帮助。

两种情况下的错误相同。我确实收到来自 gcloud auth configure-docker...

的消息
WARNING: `docker` not in system PATH.
`docker` and `docker-credential-gcloud` need to be in the same PATH in order to work correctly together.
gcloud's Docker credential helper can be configured but it will not work until this is corrected.
Adding credentials for: australia-southeast1-docker.pkg.dev
Docker configuration file updated.
INFO: Display format: "default"

我认为这是有帮助的,并告诉我它找不到安装的 docker(这是真的)但无论如何它创建了信用(也是真的)。这应该无关紧要,因为 jib 不依赖于 docker 本身,只依赖于信誉。然而还是不行。

部分问题(再次感谢@ChanseokOh 标记此问题)是我认为我使用的是 3.1.4 时仍在使用 jib 1.6.1。改变它加上其他一些东西解决了这个问题。所以这里是下一个为此苦苦挣扎的人的完整故事:

首先,这是我的 pom 文件的内容:

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>3.1.4</version>
    <configuration>
        <from>
            <image>${base.image}</image>
        </from>
        <to>
            <image>${docker.image.repo}/${project.artifactId}:latest</image>
            <tags>
                <tag>${VERSION_ID}</tag>
                <tag>latest</tag>
            </tags>
        </to>
        <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
        <allowInsecureRegistries>true</allowInsecureRegistries>
        <container>
            <ports>
                <port>8080</port>
            </ports>
        </container>
    </configuration>
    <executions>
        <execution>
            <id>build-and-push-docker-image</id>
            <phase>package</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
</plugin>

版本很重要。虽然旧版本 (1.6.1) 在本地运行良好,但在 Cloud Build 上无法运行。

我的 Cloud Build 文件如下所示:

...
  - name: 'gcr.io/cloud-builders/gcloud'
    args:
      - '-c'
      - >
        gcloud auth configure-docker --quiet --verbosity=debug `echo
        ${_CONTAINER_REPO} | cut -d / -f 1` 
        /root 
    id: gcloud auth
    entrypoint: /bin/bash
...
  - name: 'gcr.io/cloud-builders/mvn:3.5.0-jdk-8'
    args:
      - '-Dmaven.test.skip=false'
      - '-Dmaven.repo.local=/workspace/.m2/repository'
      - '--settings'
      - custom-settings.xml
      - clean
      - install
      - '-DskipITs'
      - '-B'
      - '-X'
      - '-DVERSION_ID=$TAG_NAME'
      - '-DBRANCH_ID=master'
      - '-DPROJECT_ID=$PROJECT_ID'
      - '-DCONTAINER_REPO=${_CONTAINER_REPO}'
      - '-DMAVEN_REPO=${_MAVEN_REPO}'
      - '-DDOCKER_CONFIG=/builder/home/.docker'
      - '-P'
      - release
    id: build

gcloud auth 步骤会创建 docker 凭据文件。

下一步是 Maven 构建,技巧是定义 DOCKER_CONFIG 指向 docker creds 文件的正确位置。我相信创建 docker creds 文件、定义 DOCKER_CONFIG 并获得正确的版本号都是解决方案所必需的。

有趣的是,gcr.io/cloud-builders/gcloudgcr.io/cloud-builders/mvn:3.5.0-jdk-8 仍然引用 Google 容器存储库,它已被 Artifact Repository 取代,这是我进入这个但我没有的全部原因看到这些图像的任何更新参考。 Docs are here.

为了完整起见添加另一个答案:

在基本情况下,Jib 可以在 Google Cloud Build (GCB) 上开箱即用,而无需在推送到 Google 容器注册表 (GCR) 时手动配置 Jib 的凭据(主要是在同一 GCP 项目中推送到 GCR 时)。这是因为 Jib 可能 automatically pick up the Application Default Credentials (ADC) 来自 GCB 运行的环境。但是,我不确定 GCB 上的 ADC 是否也适用于开箱即用的 Artifact Registry。

当然,您始终可以通过多种不同方式为 Jib 配置注册表凭据。