1

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

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

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

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

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

我尝试了什么?

  • 我将适当的角色添加到 Cloud Build 使用的默认服务帐户(尽管它们应该在那里)。该downloadArtifacts权限包含在角色 Artifact Registry Reader 中,因此我添加了该角色以及 Artifact Registry Writer。
  • 我切换到了不同的服务帐户(构建服务帐户,我们称之为 BSA),是的,确保具有相同的适当角色(见上文)。
  • 我将 BSA 作为主体添加到目标 GAR 并在那里为其赋予了适当的角色(变得绝望)
  • 我的用户凭据包括所有者角色,因此我将所有者角色添加到 BSA(不是我想要保留的)

所有这些都给了我相同的权限被拒绝错误。以防万一我真的误解了一些东西,我在我的 Cloud Build yaml 中添加了一个步骤来运行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_CONFIGto 指向/builder/home/.docker目录(如此处所建议),但这也无济于事。

两种情况下的错误相同。我确实收到了来自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 本身,只依赖于信誉。但是它仍然不起作用。

4

2 回答 2

0

部分问题(再次感谢@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 和获取正确的版本号都是解决方案所必需的。

An interesting aside is that gcr.io/cloud-builders/gcloud and gcr.io/cloud-builders/mvn:3.5.0-jdk-8 still reference Google Container Repository which is superseded by Artifact Repository, and is the whole reason I got into this but I have not seen any updated reference for these images. Docs are here.

于 2021-11-11T21:03:36.513 回答
0

Adding another answer for the sake of completeness:

In the basic case, Jib may work out of the box on Google Cloud Build (GCB) without manually configuring credentials for Jib when pushing to your Google Container Registry (GCR) (mostly when pushing to GCR in the same GCP project). This is because Jib may automatically pick up the Application Default Credentials (ADC) that come from the environment where GCB runs. However, I am not sure if the ADC on GCB also works for Artifact Registry out of the box.

Of course, you can always configure registry credentials for Jib in many different ways.

于 2021-11-12T01:16:38.587 回答