如何使用 HTTP API 从 gcr.io Docker 注册表中列出图像和标签?

How to list images and tags from the gcr.io Docker Registry using the HTTP API?

我正在尝试从 Node.js 中的 Google Container Registry (gcr.io) 获取可用图像及其标签的列表。

我首先使用 google-auto-auth 来获取范围为 https://www.googleapis.com/auth/devstorage.read_write 的令牌, 然后我将该令牌换成 gcr.io 令牌,如下所示:

axios.get('https://gcr.io/v2/token?service=gcr.io', {
  auth: {
    username: '_token',
    password: token // token I got from `google-auto-auth`
  }
})

然后我尝试使用它来调用 v2/_catalog 端点:

axios.get('https://gcr.io/v2/_catalog', {
  headers: {
    Authorization: `Bearer ${gcrToken}`
  }
})

我收到以下错误:

{ 
  errors: [ { code: 'DENIED', message: 'Failed to retrieve projects.' } ] 
}

很公平,它必须需要我的项目 ID,但我应该在哪里提供它?

只是为了看看我能否让其他任何东西工作,我尝试了:

axios.get('https://gcr.io/v2/my-project-id/my-image/tags/list', {
  headers: {
    Authorization: `Bearer ${gcrToken}`
  }
})

我得到以下信息:

{ 
  errors: [ 
    { 
      code: 'NAME_INVALID', 
      message: 'Requested repository does not match bearer token resource: my-project-id/my-image' 
    } 
  ] 
}

如何从 gcr.io 中读取图像信息?

第一个错误可能是因为您缺少列出项目的范围之一: https://cloud.google.com/resource-manager/reference/rest/v1/projects/list#authorization

您收到第二个错误,因为您缺少令牌交换中的范围。

你想要这样的东西:

https://gcr.io/v2/token?service=gcr.io&scope=repository:<my-project-id/my-image>:*

参见此处示例:https://docs.docker.com/registry/spec/auth/token/#requesting-a-token

在与 GCR 的 Jon Johnson 进行了广泛的沟通后,我们终于找出了问题所在。如果你赞成这个答案,请也赞成 Jon 的答案,他竭尽全力解决了这个问题。

在撰写本文时,大部分内容都没有记录。

  • 需要使用 registry:catalog:* 范围。
  • 我的图像被推送到 us.gcr.io,他们将它们视为单独的注册表 — 我以为它们是镜像。
  • 服务帐户必须在 Google Cloud IAM 中具有 Project Viewer 角色。
  • 您可以使用 GCR 令牌以及 Google 云令牌。然而,虽然 GCR 令牌不能与 Basic base64(_token:<token>) 一起使用,但 Google 云令牌可以。

获取 GCR 令牌

// Updated host
axios.get('https://us.gcr.io/v2/token?service=gcr.io', {
  params: {
    service: 'us.gcr.io',
    scope: `registry:catalog:*`
  },
  auth: {
    username: '_token',
    password: token // token I got from `google-auto-auth`
  },  
})

使用令牌列出存储库

const client = axios.create({
  baseURL: `https://us.gcr.io/v2`,
  headers: {
    Authorization: `Bearer ${token}`
  }
})

client.get('/_catalog').then((response) => {
  console.log(response.data.repositories)
})