У нас есть структура на нашей платформе, которая требует большого количества частных изображений в одном и / или только нескольких проектах, если это возможно. Кроме того, мы в значительной степени являемся магазином GCP и хотели бы оставаться в среде Google.
В настоящее время, насколько я понимаю, для структур ACL GCR требуются разрешения storage.objects.get и storage.objects.list (или роль objectViewer), связанные с учетной записью службы (в данном случае) для доступа к GCR. В общем, это не проблема, и у нас не было прямых проблем с использованием gsutil для разрешения доступа на чтение на уровне проекта для реестра контейнера. Ниже приведен пример рабочего процесса для достижения общего доступа. Однако это не позволяет достичь нашей цели - ограничить доступ к учетной записи для каждого изображения.
Simple Docker Image создается, маркируется и помещается в 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
Это предоставляет нам репозиторий hello_example в проекте ex_proj.
Мы создаем сервисную учетную запись и даем ей разрешения на чтение из корзины.
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/
В общей схеме мы хотели бы поразить следующую модель:
- Аккаунт A создал ImageA: TagA в ExampleProj
- ServiceAccountA генерируется
- ACL установлены для ServiceAccountA для доступа только к ExampleProj / ImageA и всем тегам под ним
- ServiceAccountA JSON предоставляется учетной записиA
- AccountA теперь может получить доступ только к ExampleProj / ImageA, AccountB не может получить доступ к ExampleProj / ImageA
Несмотря на то, что мы могли бы вести реестр контейнеров для каждого аккаунта для отдельного проекта, возможность масштабирования, необходимая для отслеживания проектов в рамках каждой учетной записи и прихоти к ограничениям проекта GCP в период интенсивного использования, вызывает беспокойство.
Я открыт для любых идей или структур, которые могли бы достичь этого, кроме вышеперечисленного!
EDIT
Спасибо Джонджонсону за ответ! Я написал быстрый и грязный сценарий в соответствии с рекомендациями, относящимися к чтению блобов. Я до сих пор работаю над подтверждением его успеха, но я хотел заявить, что мы контролируем, когда происходят нажатия, поэтому отслеживание результатов менее хрупко, чем в других ситуациях.
Вот скрипт, который я собрал в качестве примера для манифеста -> изменения разрешения дайджеста.
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 не идентифицируются.
Было ли это в соответствии с тем, что вы имели в виду Джонджонсон? По сути, разрешить доступ для двоичного объекта для каждой учетной записи службы на основе манифеста / слоев, связанных с этим изображением / тегом?
Спасибо!