使用 IAM 进行访问权限控制

本页面介绍控制对 Container Registry 的访问权限的权限。

配置权限后,您便可以为用于推送和拉取映像的 Docker 客户端配置身份验证

如果您使用 Artifact Analysis 来处理容器元数据(例如映像中发现的漏洞),请参阅 Artifact Analysis 文档,了解如何授予查看或管理元数据的访问权限。

准备工作

验证您拥有管理用户的权限。您必须拥有以下任一角色中的权限:

  • Project IAM Admin (roles/resourcemanager.projectIamAdmin)
  • Security Admin (roles/iam.securityAdmin)

除了授予这些角色,您还可以使用具有相同权限的自定义角色预定义角色

权限和角色

与 Container Registry 进行交互的所有用户、服务账号和其他身份都必须具有 Cloud Storage 的相应 Identity and Access Management (IAM) 权限。

  • 通常访问 Container Registry 的 Google Cloud 服务会配置同一 Google Cloud 项目中的注册表的默认权限。如果默认权限不能满足您的需求,您必须配置适当的权限。
  • 对于其他身份,您必须配置所需的权限。

您可以使用 Cloud Storage 权限控制对 Container Registry 主机的访问权限。下表列出了具有 Container Registry 所需权限的 Cloud Storage 角色

使用 Google Cloud 控制台查看 Container Registry 映像时,需要一些其他权限,请参阅使用 Cloud 控制台所需的常见权限

所需的访问权限 角色 在哪里授予权限
从现有注册表中拉取映像(只读) Storage Object Viewer (roles/storage.objectViewer) 授予对注册表存储桶的角色。
针对项目中的现有注册表主机执行映像推送(写入)和拉取(读取)操作 Storage Legacy Bucket Writer (roles/storage.legacyBucketWriter) 授予对注册表存储桶的角色。此权限仅在存储桶级层提供,您无法在项目级层授予。
将注册表主机添加到 Google Cloud 项目并创建关联的存储桶。 Storage Admin (roles/storage.admin) 授予项目级层的角色

推送映像时需要对象读写权限以及 storage.buckets.get 权限。Storage Legacy Bucket Writer 角色在单个 Cloud Storage 角色中包含所需的权限,但不会授予对存储分区和对象的完全控制权。

Storage Admin 角色可授予对存储分区和对象的完全控制权。 如果您在项目级授予此权限,则主账号将拥有对项目中所有存储分区的访问权限,包括 Container Registry 未使用的存储分区。请仔细考虑哪些主账号需要此角色。

  • 默认情况下,Cloud Build 服务账号具有 Storage Admin 角色的权限。因此,该服务账号可以通过第一次推送在其父项目中添加注册表,并将映像推送到其父项目中的现有注册表。
  • 如果您使用 Docker 或其他工具创建映像并将其推送到注册表,请考虑使用具有更高级 Storage Admin 角色的账号将注册表添加到项目中,然后向需要推送或拉取映像的其他账号授予 Storage Legacy Bucket Writer 或 Storage Object Viewer 角色。

如需详细了解 Cloud Storage 角色和权限,请参阅 Cloud Storage 文档

授予 IAM 权限

Container Registry 使用 Cloud Storage 存储分区作为容器映像的底层存储空间。您可以通过授予注册表存储分区的权限来控制对映像的访问权限。

第一次将映像推送到主机时,系统会将注册表主机及其存储桶添加到项目中。例如,第一次推送到 gcr.io/my-project 时,系统会将 gcr.io 注册表主机添加到项目 IDmy-project 的项目中,并为注册表创建一个存储桶。存储桶名称采用以下格式之一:

  • 对于存储在主机 gcr.io 上的映像,名称采用 artifacts.PROJECT-ID.appspot.com 格式
  • 对于存储在其他注册表主机上的映像,名称采用 STORAGE-REGION.artifacts.PROJECT-ID.appspot.com 格式

如需成功执行第一次映像推送,执行推送的账号必须具有 Storage Admin 角色的权限。

在初始映像推送到注册表主机后,您可以授予注册表存储分区的权限以控制对注册表中映像的访问权限:

  • Storage Legacy Bucket Writer:推送和拉取
  • Storage Object Viewer:仅拉取

您可以使用 Google Cloud 控制台或 Google Cloud CLI 授予对存储桶的权限。

局限和限制

您只能为 Container Registry 主机授予存储桶级层的权限。

  • Container Registry 会忽略对 Cloud Storage 存储桶中的单个对象设置的权限。
  • 您无法授予对注册表中代码库的权限。如果您需要更精细的访问权限控制,则 Artifact Registry 提供代码库级层的访问权限控制,可能更适合您的需求。
  • 如果您为任何 Container Registry 存储桶启用统一存储桶级层访问权限,则必须向访问您的注册表的所有用户和服务账号明确授予权限。在这种情况下,Owner 和 Editor 角色本身可能不会授予所需权限。

授予权限

  1. 如果项目中还没有注册表主机,则具有 Storage Admin 角色权限的账号必须将第一个映像推送到注册表。这会为注册表主机创建存储桶。

    Cloud Build 拥有在同一项目中执行初始映像推送所需的权限。 如果您要使用其他工具推送映像,请验证您用于向 Container Registry 进行身份验证的 Google Cloud 账号的权限。

    如需详细了解如何使用 Docker 推送初始映像,请参阅添加注册表

  2. 在使用 Container Registry 的项目中,授予注册表主机使用的 Cloud Storage 存储分区的适当权限。

    控制台

    1. 前往 Google Cloud 控制台中的 Cloud Storage 页面
    2. 点击存储桶的 artifacts.PROJECT-ID.appspot.comSTORAGE-REGION.artifacts.PROJECT-ID.appspot.com 链接。

      PROJECT-ID 替换为托管 Container Registry 的项目的 Google Cloud 项目 ID,将 STORAGE-REGION 替换为托管映像的注册表的多区域asiaeuus)。

    3. 选择权限标签。

    4. 点击添加

    5. 主账号字段中,输入需要访问权限的账号的电子邮件地址(以英文逗号分隔)。此电子邮件地址可以是以下各项之一:

      • Google 账号(例如 someone@example.com
      • Google 群组(例如 my-developer-team@googlegroups.com
      • IAM 服务账号

        请参阅通常访问注册表的 Google Cloud 服务的列表,以查找关联服务账号的电子邮件地址。如果服务不在 Container Registry 所在项目中运行,请确保您使用的是其他项目中的服务账号的电子邮件地址。

    6. 选择角色下拉菜单中,选择 Cloud Storage 类别,然后选择适当的权限。

      • Storage Object Viewer:仅拉取映像
      • Storage Legacy Bucket Writer:推送和拉取映像
    7. 点击添加

    gcloud

    1. 运行以下命令列出项目中的存储分区:

      gcloud storage ls
      

      响应如下例所示:

      gs://[BUCKET_NAME1]/
      gs://[BUCKET_NAME2]/
      gs://[BUCKET_NAME3]/ ...
      

      在返回的存储桶列表中找到注册表主机的存储桶。存储映像的存储桶的名称 BUCKET-NAME 采用以下格式之一:

      • 对于存储在主机 gcr.io 上的映像,名称采用 artifacts.PROJECT-ID.appspot.com 格式
      • 对于存储在其他注册表主机上的映像,名称采用 STORAGE-REGION.artifacts.PROJECT-ID.appspot.com 格式

      其中

      • PROJECT-ID 是您的 Google Cloud 项目 ID
      • STORAGE-REGION 是存储分区的位置:
        • us(适用于主机 us.gcr.io 中的注册表)
        • eu(适用于主机 eu.gcr.io 中的注册表)
        • asia(适用于主机 asia.gcr.io 中的注册表)
    2. 在 shell 或终端窗口中运行以下命令:

      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
      --member=TYPE:EMAIL-ADDRESS \
      --role=ROLE
      

      地点

      • BUCKET_NAME 是格式为 artifacts.PROJECT-ID.appspot.comSTORAGE-REGION.artifacts.PROJECT-ID.appspot.com 的 Cloud Storage 存储分区的名称
      • TYPE 可以是以下各项之一:
        • serviceAccount(如果 EMAIL-ADDRESS 指定服务账号)。
        • user(如果 EMAIL-ADDRESS 是 Google 账号)。
        • group(如果 EMAIL-ADDRESS 是 Google 群组)。
      • EMAIL-ADDRESS 可以是下列选项之一:

        • Google 账号(例如 someone@example.com
        • Google 群组(例如 my-developer-team@googlegroups.com
        • IAM 服务账号

          请参阅通常访问注册表的 Google Cloud 服务的列表,以查找关联服务账号的电子邮件地址。如果服务不在 Container Registry 所在项目中运行,请确保您使用的是其他项目中的服务账号的电子邮件地址。

      • ROLE 是您要授予的 Cloud Storage 角色。

        • objectViewer:拉取映像
        • legacyBucketWriter:推送和拉取映像

    例如,以下命令会向服务账号 my-account@my-project.iam.gserviceaccount.com 授予在存储分区 my-example-bucket 中推送和拉取映像的权限:

    gcloud storage buckets add-iam-policy-binding gs://my-example-bucket \
      --member=serviceAccount:my-account@my-project.iam.gserviceaccount.com \
      --role=roles/storage.objectUser
    

    gcloud storage buckets add-iam-policy-binding 命令会更改托管镜像仓库的存储分区的 IAM 权限。如需查看其他示例,请参阅 gcloud CLI 文档

  3. 如果您要为将映像推送到 Container Registry 的 Compute Engine 虚拟机或 GKE 节点配置访问权限,请参阅配置虚拟机和集群,了解其他配置步骤。

配置对映像的公共访问权限

如果主机位置的底层存储分区可公开访问,则 Container Registry 便可公开访问。在项目范围内,每个主机位置中的所有映像要么都公开,要么都不公开。 不能仅公开提供一个项目主机中的特定映像。如果您想要公开特定映像,请按以下所述操作:

  • 确保将这些映像保存在您公开的一个单独主机位置中,或者
  • 创建一个新项目来存储可公开访问的映像。

如需公开提供容器映像,请按照以下步骤将底层存储分区设为可公开访问:

  1. 确保已将映像推送到 Container Registry,以使系统创建底层存储分区。

  2. 找到该注册表对应的 Cloud Storage 存储分区名称。为此,请列出各存储分区:

    gcloud storage ls
    

    您的 Container Registry 存储分区网址将列为 gs://artifacts.PROJECT-ID.appspot.comgs://STORAGE-REGION.artifacts.PROJECT-ID.appspot.com,其中:

    • PROJECT-ID 是您的 Google Cloud 项目 ID网域级项目将域名作为项目 ID 的一部分。
    • STORAGE-REGION 是存储分区的位置:
      • us(适用于主机 us.gcr.io 中的注册表)
      • eu(适用于主机 eu.gcr.io 中的注册表)
      • asia(适用于主机 asia.gcr.io 中的注册表)
  3. 运行以下命令,将 Container Registry 的存储分区设为可公开访问。此命令将使存储分区中的所有映像都可公开访问。

    gcloud storage buckets add-iam-policy-binding gs://BUCKET-NAME \
        --member=allUsers --role=roles/storage.objectViewer
    

    其中:

    • gs://BUCKET-NAME 是 Container Registry 的存储分区网址

移除对图片的公开访问权限

控制台

  1. 确保已将映像推送到 Container Registry,以使系统创建底层存储分区。

  2. 在 Google Cloud 控制台中打开 Container Registry 页面。

    打开 Container Registry 页面

  3. 在左侧面板中,点击设置

  4. 设置页面的公共访问权限下,将公开范围切换为不公开。此设置用于控制对底层存储分区的访问。

gcloud storage

  1. 找到该注册表对应的 Cloud Storage 存储分区名称。为此,请列出各存储分区:

    gcloud storage ls
    

    您的 Container Registry 存储分区网址将列为 gs://artifacts.PROJECT-ID.appspot.comgs://STORAGE-REGION.artifacts.PROJECT-ID.appspot.com,其中:

    • PROJECT-ID 是您的 Google Cloud 控制台 项目 ID网域级项目将域名作为项目 ID 的一部分。
    • STORAGE-REGION 是存储分区的位置:
      • us(适用于主机 us.gcr.io 中的注册表)
      • eu(适用于主机 eu.gcr.io 中的注册表)
      • asia(适用于主机 asia.gcr.io 中的注册表)
  2. 如需移除对存储桶的公开访问权限,请在 shell 或终端窗口中运行以下命令:

    gcloud storage bucket remove-iam-policy-binding gs://BUCKET-NAME \
      --member=allUsers --role=roles/storage.objectViewer
    

其中:

  • BUCKET-NAME 是所需存储分区的名称

撤消权限

按照以下步骤操作以撤消 IAM 权限。

控制台

  1. 访问 Google Cloud 控制台中的 Cloud Storage 页面
  2. 点击存储桶的 artifacts.PROJECT-ID.appspot.comSTORAGE-REGION.artifacts.PROJECT-ID.appspot.com 链接。其中,PROJECT-ID 是托管 Container Registry 的项目的 Google Cloud 项目 ID,而 STORAGE-REGION 是托管映像的注册表的多区域asiaeuus)。

  3. 选择权限标签。

  4. 点击要移除的任何主账号旁边的垃圾箱图标。

gcloud

在 shell 或终端窗口中运行以下命令:

gcloud storage bucket remove-iam-policy-binding gs://BUCKET-NAME \
    --member=PRINCIPAL --all

其中:

  • BUCKET-NAME 是所需存储分区的名称
  • PRINCIPAL 可以是以下各项之一:
    • user:EMAIL-ADDRESS(适用于 Google 账号)
    • serviceAccount:EMAIL-ADDRESS(适用于 IAM 服务账号)
    • group:EMAIL-ADDRESS(适用于 Google 群组)。
    • allUsers(用于撤消公开访问权限)

与 Google Cloud 服务集成

对于大多数 Google Cloud 服务账号,配置对注册表的访问权限只需授予适当的 IAM 权限。

Google Cloud 服务的默认权限

Cloud Build 或 Google Kubernetes Engine 等 Google Cloud 服务使用默认服务账号服务代理与同一项目中的资源进行交互。

在下列情况下,您必须自行配置或修改权限:

  • Google Cloud 服务与 Container Registry 属于不同的项目。
  • 默认权限不能满足您的需求。例如,默认的 Compute Engine 服务账号对同一项目中的存储空间具有只读权限。如果要将虚拟机中的映像推送到注册表,您必须修改虚拟机服务账号的权限,或使用具有存储空间写入权限的账号向注册表进行身份验证。
  • 您使用自定义服务账号与 Container Registry 进行交互

以下服务账号通常访问 Container Registry。服务账号的电子邮件地址包含运行服务的项目的 Google Cloud 项目 ID 或项目编号

服务 服务账号 电子邮件地址 权限
App Engine 柔性环境 App Engine 默认服务账号 PROJECT-ID@appspot.gserviceaccount.com Editor 角色,可以读取和写入存储空间
Compute Engine Compute Engine 默认服务账号 PROJECT-NUMBER-compute@developer.gserviceaccount.com Editor 角色,仅拥有对存储空间的只读权限
Cloud Build Cloud Build 服务账号 PROJECT-NUMBER@cloudbuild.gserviceaccount.com 默认权限包括创建存储分区以及读写存储空间。
Cloud Run Compute Engine 默认服务账号
修订版本的默认运行时服务账号。
PROJECT-NUMBER-compute@developer.gserviceaccount.com Editor 角色,仅拥有对存储空间的只读权限
GKE Compute Engine 默认服务账号
节点的默认服务账号。
PROJECT-NUMBER-compute@developer.gserviceaccount.com Editor 角色,仅拥有对存储空间的只读权限

配置虚拟机和集群以推送映像

Compute Engine 以及任何使用 Compute Engine 的 Google Cloud 服务都将 Compute Engine 默认服务账号用作默认身份。

IAM 权限和访问权限范围会影响虚拟机读写存储空间的能力。

  • IAM 权限决定了是否能够访问资源。
  • 对于通过 gcloud CLI 和虚拟机实例上的客户端库发出的请求,访问权限范围决定了这些请求的默认 OAuth 范围。因此,在使用应用默认凭据进行身份验证时,访问权限范围可以进一步限制对 API 方法的访问。
    • 如需拉取私有映像,虚拟机服务账号必须具有映像存储分区的 read 权限。
    • 如需推送私有映像,虚拟机服务账号必须具有映像存储分区的 read-writecloud-platformfull-control 访问权限范围。

默认情况下,Compute Engine 默认服务账号具有 Editor 角色,其中包含为大多数 Google Cloud 服务创建和更新资源的权限。但是,对于与虚拟机关联的默认服务账号或自定义服务账号,存储分区的默认访问权限范围都是只读。这意味着,默认情况下,虚拟机无法推送映像。

如果您只打算将映像部署到 Compute Engine 和 GKE 等环境,则无需修改访问权限范围。如果您希望在这些环境中运行将映像推送到注册表的应用,则必须执行其他配置。

以下设置需要更改 IAM 权限或访问权限范围配置。

从虚拟机或集群推送映像
如果要推送映像,虚拟机实例服务账号必须具有 storage-rw 范围,而不是 storage-ro
虚拟机和 Container Registry 位于不同的项目中
您必须向服务账号授予 IAM 权限以访问 Container Registry 使用的存储分区。
在虚拟机上运行 gcloud 命令
服务账号必须具有 cloud-platform 范围。此范围授予推送和拉取映像以及运行 gcloud 命令的权限。

以下部分介绍了配置范围的步骤。

为虚拟机配置范围

如需在创建虚拟机时设置访问权限范围,请使用 --scopes 选项。

gcloud compute instances create INSTANCE --scopes=SCOPE

其中

  • INSTANCE 是虚拟机实例名称。
  • SCOPE 是您要为虚拟机服务账号配置的范围:
    • 拉取映像:storage-ro
    • 拉取并推送映像:storage-rw
    • 如需拉取并推送映像,请运行 gcloud 命令:cloud-platform

如需更改现有虚拟机实例的范围,请执行以下操作:

使用 --scopes 选项设置访问权限范围。

  1. 停止虚拟机实例。请参阅停止实例

  2. 使用以下命令更改访问权限范围。

    gcloud compute instances set-service-account INSTANCE --scopes=SCOPE
    

    其中

    • INSTANCE 是虚拟机实例名称。
    • SCOPE 是您要为虚拟机服务账号配置的范围:
      • 拉取映像:storage-ro
      • 拉取并推送映像:storage-rw
      • 如需拉取并推送映像,请运行 gcloud 命令:cloud-platform
  3. 重启虚拟机实例。请参阅启动已停止的实例

如果要为虚拟机使用自定义服务账号而不是默认服务账号,则您可以在创建虚拟机修改虚拟机设置时指定要使用的服务账号和访问权限范围。

为 Google Kubernetes Engine 集群配置范围

默认情况下,创建新的 GKE 集群时,系统会为其分配针对 Cloud Storage 存储分区的只读权限。

如需在创建 Google Kubernetes Engine 集群时设置 read-write 存储范围,请使用 --scopes 选项。例如,以下命令会创建一个范围为 bigquerystorage-rwcompute-ro 的集群:

gcloud container clusters create example-cluster \
--scopes=bigquery,storage-rw,compute-ro

如需详细了解创建新集群时可设置的范围,请参阅 gcloud container clusters create 命令的文档。

Container Registry 服务账号

Container Registry Service Agent 在与 Google Cloud 服务交互时会代表 Container Registry 执行操作。如果您在 2020 年 10 月 5 日之后启用 Container Registry API,则该服务代理具有所需的最小权限集。服务代理之前具有 Editor 角色。如需详细了解服务代理以及如何修改其权限,请参阅 Container Registry 服务账号

自行试用

如果您是 Google Cloud 新手,请创建一个账号来评估 Container Registry 在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。

免费试用 Container Registry