有关在 Google Cloud 中构建和部署应用的更改

本文档将引导您了解在使用 Cloud Build 构建容器映像并将其部署到 Google Cloud 运行时环境(例如 Cloud Run 或 Google Kubernetes Engine)时,Container Registry 和 Artifact Registry 之间的区别。

在本指南中,比较侧重于标准 Artifact Registry 独立代码库、常规 Artifact Registry 代码库 并支持所有 Artifact Registry 功能。如果您的管理员设置了具有 gcr.io 网域支持的代码库,系统会自动将对 gcr.io 主机名的请求重定向到相应的 Artifact Registry 代码库,并且有权访问 Container Registry 的默认服务账号对 Artifact Registry 也有等效的默认权限。

了解 Container Registry 和 有关使用 Docker 客户端的 Artifact Registry,请参阅 对使用 Docker 进行推送和拉取的变更

您可以参考这些信息,调整现有的命令、配置或文档,使其适用于将 Container Registry 与 Cloud Build 搭配使用。

准备工作

本文档假定您满足以下条件:

  1. 在您的项目中启用 Artifact Registry
  2. 启用了 Cloud Build API,以及您与 Artifact Registry 搭配使用的任何其他 Google Cloud 服务的 API。

工作流程变更

如果您在同一个项目中将 Cloud Build 与 Container Registry 搭配使用, 工作流如下所示:

  1. 使用 Dockerfile构建配置文件,通过 Cloud Build 构建映像、为其添加标记并将其推送到代码库。

    以下示例构建映像 my-image,使用 tag1 标记该映像, 将其推送到项目 my-project 中的主机 gcr.io

    gcloud builds submit --tag gcr.io/my-project/my-image:tag1
    
  2. Google Cloud 运行时环境(例如 Cloud Run 和 Google Kubernetes Engine)会从注册表中拉取映像。

    例如,以下命令会将上一步中的映像部署到 Cloud Run 作为 my-service

    gcloud run deploy my-service --image gcr.io/my-project/my-image:tag1
    

Container Registry 工作流将管理员职责与 构建和部署应用

  • 启用某些 Google Cloud API 后, Container Registry API 会自动启用。这意味着,这些服务的用户对同一项目中的 Container Registry 具有隐式访问权限。对于 例如,可以在 Cloud Build 中运行构建作业的用户可以 和添加注册表主机。
  • Cloud Build 服务账号 权限 创建 Cloud Storage 存储分区。这意味着,该账号在首次将映像推送到主机时,可以自动将 Container Registry 主机添加到项目中。这也意味着 在整个项目中创建、读取和写入存储分区, 包括 Container Registry 未使用的存储分区。

在 Artifact Registry 中,管理员和 更改构建和部署工作流中的步骤的构建角色。调整 适用于 Artifact Registry 的 Container Registry 工作流,请执行以下操作: 更改。每个步骤都链接到有关修改工作流的更多信息。

  1. 新功能启用 Artifact Registry API。

    您必须启用 Artifact Registry API。Cloud Build 和运行时环境,例如 Cloud Run 和 GKE 不会为您自动启用该 API。

  2. 新建:如果目标 Docker 仓库尚不存在,则创建目标 Docker 仓库。您必须先创建一个仓库,然后才能向其推送映像。推送映像不会触发代码库的创建 Cloud Build 服务账号无权创建 代码库

  3. 已更改构建映像、标记映像以及将映像推送到代码库 与 Cloud Build 搭配使用(使用 Dockerfile 或构建配置文件)。

    以下示例命令与 Container Registry 示例相同 但使用的是映像的 Artifact Registry 代码库路径。

    gcloud builds submit --tag us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1
    
  4. 变更:将映像部署到 Google Cloud 运行时 例如 Cloud Run 或 GKE

    以下示例命令与 Container Registry 示例相同 但使用的是映像的 Artifact Registry 代码库路径。

    gcloud run deploy my-service --image us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1
    

此外,Artifact Registry 使用与 Container Registry 不同的角色 来控制对映像的访问权限您需要配置权限 以下情况:

  • Cloud Build 或 Google Cloud 运行时环境 与 Artifact Registry 不同
  • 您为 Google Cloud 服务(例如 Cloud Build 或 GKE)使用自定义服务账号,而不是默认服务账号。
  • 您已向其他用户或服务账号授予权限。

启用 API

要点:

以下对比介绍了如何为每项服务启用该 API:

Container Registry

启用以下 Google Cloud API 后,Container Registry API 也会自动启用:

  • App Engine 柔性环境
  • Cloud Build
  • Cloud Run 函数
  • Cloud Run
  • Artifact Analysis 中的容器扫描或按需扫描
  • Google Kubernetes Engine

默认情况下,如果用户可以在 Cloud Build 中运行 build、使用 Artifact Analysis 扫描容器或将容器部署到 Google Cloud 运行时,则当 Container Registry 位于同一项目中时,他们会隐式拥有对 Container Registry 中映像的访问权限。

Artifact Registry

您必须启用 Artifact Registry API。此类服务包括 Cloud Build、Cloud Run 和 GKE 不自动启用 Artifact Registry API。

您可以使用 gcloud 在同一项目中启用多个 API。例如,如需启用 Cloud Build API 和 Artifact Registry API,请运行以下命令:

gcloud services enable
    artifactregistry.googleapis.com \
    cloudbuild.googleapis.com

添加注册库和代码库

要点:

  • 在推送之前,您必须创建 Artifact Registry Docker 代码库 添加一张图片。
  • Container Registry 会将所有映像存储在同一多区域位置的同一存储桶中。在 Artifact Registry 中,您可以在同一区域或多区域中创建多个代码库,并为其设置单独的访问权限政策。

以下对比介绍了每项服务中的代码库设置:

Container Registry

在 Container Registry 中,您最多可向项目添加四个注册表主机。 您可以通过推送第一个映像来添加注册表主机。

  1. 要将 gcr.io 等注册表添加到您的项目,请使用 项目级别的 Storage Admin 角色推送初始映像。

    例如,如果项目 my-project 中不存在 gcr.io 主机,则推送映像 gcr.io/my-project/my-image:1.0 会触发以下步骤:

    1. gcr.io 主机添加到项目中
    2. 在项目中为 gcr.io 创建一个存储桶。
    3. 将图片存储为 gcr.io/my-project/my-image:1.0
  2. 完成此初始推送后,您可以为其他用户授予对存储桶的权限

默认情况下,Cloud Build 具有 权限 即创建存储桶,因此初始映像推送和后续推送 难以区分。

在项目中,注册表主机会将所有映像存储在同一存储桶中。在以下示例中,项目 my-project 在注册表 gcr.io 中有两个名为 web-app 的映像。一个位于项目 ID my-project 直接下方。另一个映像位于仓库 team1 中。

gcr.io/my-project/web-app
gcr.io/my-project/team1/web-app

Artifact Registry

Cloud Build 无权在 Artifact Registry pkg.dev 网域中创建标准仓库。

具有 Artifact Registry 代码库管理员角色的账号必须先创建代码库,然后您才能将映像推送到该代码库。然后,您可以 授予其他用户对代码库的权限。

在 Artifact Registry 中,每个代码库都是独立的资源。因此, 所有映像路径都必须包含仓库

有效的映像路径:

us-central1-docker.pkg.dev/my-project/team1/web-app:1.0
us-central1-docker.pkg.dev/my-project/team2/web-app:1.0

映像路径无效(不包含代码库):

us-central1-docker.pkg.dev/my-project/web-app:1.0

以下示例展示了将映像推送到 缺失代码库失败。

  • 如果 us-central1-docker.pkg.dev/my-project/team1 不存在,则将映像推送到 us-central1-docker.pkg.dev/my-project/team1
  • us-central1-docker.pkg.dev/my-project/team1 存在但 us-central1-docker.pkg.dev/my-project/team2 不存在时,将映像推送到 us-central1-docker.pkg.dev/my-project/team2

授予权限

要点:

  • Google Cloud 服务对 Container Registry 和 Artifact Registry 具有等效的读取或写入权限。不过,默认的 Cloud Build 服务账号无法在 pkg.dev 网域上创建标准仓库。
  • 向其他有权访问 Artifact Registry 的账号授予适当的 Artifact Registry 角色。
  • Container Registry 支持在存储桶级层进行访问权限控制。Artifact Registry 支持代码库级层的访问权限控制。

下表比较了每项服务的权限:

Container Registry

Container Registry 使用 Cloud Storage 角色来控制访问权限。Cloud Build 具有所需权限 将 Container Registry 主机添加到项目中。

存储桶级别的 Storage Object Viewer
从项目中的现有注册表主机拉取(读取)映像。
存储桶级别的 Storage Legacy Bucket Writer
为项目中的现有注册表主机推送(写入)和拉取(读取)映像。
项目级别的 Storage Admin
将初始映像推送到主机,以向项目添加注册表主机。

将初始映像推送到注册表后,您可以向以下用户授予 Cloud Storage 角色: 需要访问该存储桶的其他账号。请注意,具有 Storage Admin 角色的所有权限的任何账号都可以读取、写入和删除整个项目中的存储桶和存储对象。

存储桶的权限适用于注册表中的所有代码库。 例如,对 Cloud Storage 存储分区拥有 Storage Object Viewer 权限的用户 gcr.io/my-project 的存储桶可以读取以下所有代码库中的图片:

gcr.io/my-project/team1
gcr.io/my-project/team2
gcr.io/my-project/test
gcr.io/my-project/production

Artifact Registry

Artifact Registry 有自己的角色来控制访问权限。这些角色可在管理员角色和代码库用户角色之间进行明确分离。

Cloud Build 拥有权限 Artifact Registry Writer 角色 在 pkg.dev 网域上使用标准代码库拉取映像。

只有管理代码库的账号才应具有 Artifact Registry Repository Administrator 或 Artifact Registry Administrator 角色。

Artifact Registry Reader
列出工件和代码库。下载工件。
Artifact Registry Writer
列出工件和代码库。下载制品,上传新制品 以及添加或更新代码。
Artifact Registry Repository Administrator
Artifact Registry Writer 权限以及删除工件和标记的权限。
Artifact Registry Administrator
Artifact Registry 代码库管理员权限,以及创建、更新、删除代码库和向代码库授予权限的权限。

您可以在代码库级别应用这些权限。例如:

  • 向“us-central1-docker.pkg.dev/my-project/team1”的团队 1 授予访问权限
  • 向 Team 2 授予对 us-central1-docker.pkg.dev/my-project/team2 的访问权限。

如需详细了解如何授予 Artifact Registry 权限,请参阅访问权限控制文档。

构建和推送映像

要点:

  • 在推送之前,您必须创建 Artifact Registry Docker 代码库 添加一张图片。
  • Artifact Registry 主机名不同于 Container Registry 主机名。

Cloud Build 只需一步即可构建、标记和推送映像。

借助 Container Registry,Cloud Build 可以成功将映像推送到 Google Cloud 项目中尚不存在的注册表主机。对于 初始映像推送后,Cloud Build 有权自动 将注册表主机添加到项目中。

如需调整 Container Registry 工作流,请执行以下操作:

  1. 请先设置代码库,然后再将映像推送到这些代码库。
  2. 在您的、构建配置文件或 gcloud builds submit 中更新映像路径 命令。

使用构建配置文件进行构建

将您构建的映像的 Container Registry 路径替换为现有 Artifact Registry 制品库的路径。

以下示例 cloudbuild.yaml 文件会构建映像 us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1:

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: [ 'build', '-t', 'us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1', '.' ]
images:
- 'us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1'

然后,您可以使用以下命令构建映像:

gcloud builds submit --config cloudbuild.yaml

使用 Dockerfile 进行构建

将您构建的映像的 Container Registry 路径替换为现有 Artifact Registry 制品库的路径。

以下示例命令用于构建映像 us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1 以及 当前目录中的 Dockerfile

gcloud builds submit --tag us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1

部署映像

要点:

  • Artifact Registry 主机名与 Container Registry 的主机名不同 主机名。

如需调整 Container Registry 工作流,请更新部署中的映像路径 以及配置和部署命令以下部分展示了 Cloud Build、Cloud Run 和 GKE 方法适用于部署映像的任何其他 Google Cloud 服务。

Cloud Build

使用 现有 Artifact Registry 代码库的路径。

以下示例 cloudbuild.yaml 文件会部署示例图片 us-docker.pkg.dev/cloudrun/container/hello

steps:
- name: 'gcr.io/cloud-builders/gcloud'
  args:
  - 'run'
  - 'deploy'
  - 'cloudrunservice'
  - '--image'
  - 'us-docker.pkg.dev/cloudrun/container/hello'
  - '--region'
  - 'us-central1'
  - '--platform'
  - 'managed'
  - '--allow-unauthenticated'

Cloud Run

使用 现有 Artifact Registry 代码库的路径。

例如,此命令会将示例映像 us-docker.pkg.dev/cloudrun/container/hello

gcloud run deploy my-service --image us-docker.pkg.dev/cloudrun/container/hello

GKE

将您构建的映像的 Container Registry 路径替换为 现有 Artifact Registry 代码库的路径。

以下 Artifact Registry 示例使用示例映像 us-docker.pkg.dev/artifact-registry-samples/containers/gke/hello-app:1.0

从命令行创建集群:

kubectl create deployment hello-server --image=us-docker.pkg.dev/artifact-registry-samples/containers/gke/hello-app:1.0

在部署清单中指定映像:

In a deployment manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      run: my-app
  template:
    metadata:
      labels:
        run: my-app
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/artifact-registry-samples/containers/gke/hello-app:1.0