【问题标题】:Google Container Registry Per Image ACLsGoogle Container Registry Per Image ACL
【发布时间】:2018-12-08 00:03:21
【问题描述】:

我们平台内的结构要求在单个和/或仅在可能的几个项目中包含大量私有图像。此外,我们主要是一家 GCP 商店,很乐意留在 Google 环境中。

目前 - 据我了解 - GCR ACL 结构需要附加到服务帐户(在本例中)的 storage.objects.get 和 storage.objects.list 权限(或 objectViewer 角色)才能访问 GCR。这通常不是问题,我们在使用 gsutil 为容器注册表启用项目级别的读取访问方面没有任何直接问题。以下是我们为实现一般访问所做的工作流示例。但是,它并没有实现我们限制每个图像访问的服务帐户的目标。


使用 exproj 代替使用的项目名称来构建、标记并推送到 GCR 中的简单 Docker 映像。

sudo docker build -t hello_example:latest
sudo docker tag hello_example:latest gcr.io/exproj/hello_example:latest
sudo docker push gcr.io/exproj/hello_example:latest

这为我们提供了 ex_proj 项目中的 hello_example 存储库。 我们创建一个服务帐户并授予它读取存储桶的权限。

gsutil acl ch -u gcr-read-2@exproj.iam.gserviceaccount.com:R gs://artifacts.exproj.appspot.com/
Updated ACL on gs://artifacts.exproj.appspot.com

这允许我们通过密钥使用 Docker 登录。

sudo docker login -u _json_key --password-stdin https://gcr.io < gcr-read-2.json
Login Succeeded

然后按预期从注册表中拉取镜像

sudo docker run gcr.io/exproj/hello_example

但是,出于我们的目的,我们不希望服务帐户可以访问每个项目的整个注册表,而是只能访问 hello_example,如上所述。在我使用 gsutil 的测试中,我无法定义特定的基于每个图像的 ACL,但是,我想知道我是否只是遗漏了一些东西。

gsutil acl ch -u gcr-read-2@exproj.iam.gserviceaccount.com:R gs://artifacts.exproj.appspot.com/hello_example/
CommandException: No URLs matched: gs://artifacts.exproj.appspot.com/hello_example/

总体而言,我们希望实现以下模型:

  • AccountA 在 ExampleProj 中创建了 ImageA:TagA
  • ServiceAccountA 已生成
  • 为 ServiceAccountA 设置了 ACL,以仅访问 ExampleProj/ImageA 及其下的所有标签
  • ServiceAccountA JSON 提供给 AccountA
  • AccountA 现在只能访问 ExampleProj/ImageA,AccountB 无法访问 AccountA 的 ExampleProj/ImageA

虽然我们可以按项目按账户进行容器注册,但需要跨账户跟踪项目以及在大量使用期间随心所欲地受到 GCP 项目限制的扩展潜力令人担忧。

除了上述之外,我也愿意接受任何可以实现这一目标的想法或结构!


编辑

感谢 jonjohnson 的回复!我按照与 blob 读取有关的推荐行编写了一个快速而肮脏的脚本。我仍在努力验证它是否成功,但是,我确实想声明我们确实控制了何时发生推送,因此跟踪结果不如在其他情况下那么脆弱。

这是我整理的一个脚本,作为清单 -> 摘要权限修改的示例。

require 'json'

# POC GCR Blob Handler
# ---
# Hardcoded params and system calls for speed
# Content pushed into gcr.io will be at gs://artifacts.{projectid}.appspot.com/containers/images/ per digest

def main()
    puts "Running blob gathering from manifest for org_b and example_b"
    manifest = `curl -u _token:$(gcloud auth print-access-token) --fail --silent --show-error https://gcr.io/v2/exproj/org_b/manifests/example_b`
    manifest = JSON.parse(manifest)
    # Manifest is parsed, gather digests to ensure we allow permissions to correct blobs
    puts "Gathering digests to allow permissions"
    digests = Array.new
    digests.push(manifest["config"]["digest"])
    manifest["layers"].each {|l| digests.push(l["digest"])}
    # Digests are now gathered for the config and layers, loop through the digests and allow permissions to the account
    puts "Digests are gathered, allowing read permissions to no-perms account"
    digests.each do |d|
        puts "Allowing permissions for #{d}"
        res = `gsutil acl ch -u no-perms@exproj.iam.gserviceaccount.com:R gs://artifacts.exproj.appspot.com/containers/images/#{d}`
        puts res
    end
    puts "Permissions changed for org_b:example_b for no-perms@exproj.iam.gserviceaccount.com"
end

main()

虽然这确实设置了适当的权限,但我发现对 Docker 的实际身份验证存在相当多的脆弱性,并且在未识别 Docker 登录方面被拉低。

这是否与您所说的强强森一致?基本上允许基于与该图像/标签关联的清单/层访问每个服务帐户的每个 blob?

谢谢!

【问题讨论】:

  • 您可以尝试定位 gs://artifacts.exproj.appspot.com/containers/repositories/library/hello_example/ 吗?错误消息表明您的目标网址不正确,请尝试运行 gsutil ls gs://artifacts.exproj.appspot.com/ 并继续运行该命令在存储桶中向下移动,直到找到您的图像
  • 感谢您的建议!我确实检查了,也许这就是我将 docker 图像推送到 GCR 中的方式,但是,我的存储桶的结构没有上述结构。我看到 gs://artifacts.exproj.appspot.com/containers/images/ 并且 /images 文件夹包含我与清单相关的摘要。
  • Re: docker login - 你可能遇到了过期的凭据。 GCR 人员建议使用 docker credential helper 或(如果您不能使用 cred helper)JSON 密钥:cloud.google.com/container-registry/docs/…
  • 我正在使用sudo docker login -u _json_key --password-stdin https://gcr.io &lt; access-key.json 方法,但是,这绝对有可能是到期或时间问题被卷入其中。我将针对生成 -> ACL 定义 -> 和访问运行一些测试。谢谢!

标签: docker google-cloud-platform google-container-registry google-iam


【解决方案1】:

目前没有一种简单的方法可以做你想做的事。

您可以做的一件事是为每个图像授予对存储桶中各个 blob 的访问权限。这不是很优雅,因为您必须在每次推送后更新权限。

您可以通过使用 GCR 中的 pubsub 支持来自动执行此操作以侦听推送,查看该图像引用的 blob,将存储库路径与需要访问的任何服务帐户匹配,然后授予这些服务帐户对每个服务帐户的访问权限blob 对象。

一个缺点是每个服务帐户仍然可以查看图像清单(本质上是层摘要列表 + 一些图像运行时配置)。但是,他们将无法提取实际的图像内容。

另外,这有点依赖于 GCR 的一些实现细节,所以它可能会在未来中断。

【讨论】:

  • 您好,感谢您的回复!根据您的建议和围绕它的潜在问题,我添加到我的顶级编辑。
  • 接受这个作为答案,因为我能够解决 blob ACL 来让它工作。但是,我们可能会朝着不同的方向前进以确保分离,但仍会在内部使用 Container Registry。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 2016-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多