Docker Google容器注册表每映像ACL
我们的平台结构要求在单个和/或少数项目(如果可能)中提供大量私有图像。此外,我们在很大程度上是一家GCP商店,希望留在谷歌环境中 目前,据我所知,GCR ACL结构需要附加到服务帐户(在本例中)的storage.objects.get和storage.objects.list权限(或objectViewer角色)才能访问GCR。这通常不是问题,使用gsutil在项目级别为容器注册表启用读取访问也没有任何直接问题。下面是一个工作流示例,说明了我们为实现通用访问所做的工作。但是,它并没有实现我们限制每个映像访问的服务帐户的目标Docker Google容器注册表每映像ACL,docker,google-cloud-platform,google-container-registry,google-iam,Docker,Google Cloud Platform,Google Container Registry,Google Iam,我们的平台结构要求在单个和/或少数项目(如果可能)中提供大量私有图像。此外,我们在很大程度上是一家GCP商店,希望留在谷歌环境中 目前,据我所知,GCR ACL结构需要附加到服务帐户(在本例中)的storage.objects.get和storage.objects.list权限(或objectViewer角色)才能访问GCR。这通常不是问题,使用gsutil在项目级别为容器注册表启用读取访问也没有任何直接问题。下面是一个工作流示例,说明了我们为实现通用访问所做的工作。但是,它并没有实现我们限制
简单的Docker映像被构建、标记并推送到GCR中,使用exproj代替使用的项目名称
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_示例存储库。
我们创建一个服务帐户,并授予它读取bucket的权限
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
但是,出于我们的目的,我们不希望允许服务帐户访问每个项目的整个注册表,而是只访问上面标识的hello_示例。在使用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
编辑 感谢强生的回应!我按照推荐的关于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进行访问
谢谢 目前没有一种简单的方法来做你想做的事 您可以做的一件事是为每个图像授予对bucket中单个blob的访问权限。这并不是非常优雅,因为每次推送后都必须更新权限 通过使用GCR中的支持来监听推送,查看该映像引用的blob,将存储库路径匹配到需要访问的服务帐户,然后授予这些服务帐户访问每个blob对象的权限,您可以自己实现自动化 一个缺点是每个服务帐户仍然能够查看映像清单(本质上是一个层摘要列表+一些映像运行时配置)。不过,他们将无法提取实际的图像内容
此外,这有点依赖于GCR的一些实现细节,因此将来可能会中断。嘿,感谢您的回复!我根据您的建议和围绕它的潜在问题将编辑添加到我的顶层。接受这一回答,因为我能够围绕blob ACL工作,以使其正常工作。然而,我们可能会朝着另一个方向前进,以确保分离,但仍然在内部使用容器注册表。谢谢你能试着定位gs://artifacts.exproj.appspot.com/containers/repositories/library/hello_example/?错误消息意味着您的目标URL不正确,请尝试运行gsutil ls gs://artifacts.exproj.appspot.com/,并继续运行向下移动到存储桶的命令,直到找到您的图像谢谢您的想法!我确实检查过,也许是我如何将docker图像推送到GCR中的,但是,我的bucket是这样构造的,没有上面的结构。我看到了gs://artifacts.exproj.appspot.com/containers/images/,并且/images文件夹包含了我与清单相关的摘要。Re:docker login--您可能遇到了过期的凭据。GCR人员建议使用docker凭证助手或(如果您不能使用cred助手)JSON密钥:我使用的是
sudo docker login-u\u JSON\u密钥——密码stdinhttps://gcr.io
method,但是,很有可能是过期或计时问题。我将对generation->ACL定义->和access运行一些测试。谢谢
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()