Google Cloud Deploy 和 Cloud Run 实验

本文档是一个实验教程,可帮助您快速上手使用 Google Cloud Deploy 中的交付流水线(用于将容器部署到 Cloud Run)。在本教程中,您将拥有以两个环境(devprod)为目标的 Cloud Run 的 CD 流水线。您可以通过流水线阶段部署和推广新的容器映像,并在 Google Cloud Console 上观看该过程。

本教程依赖于多项 Google Cloud 服务(尤其是 Config Controller),包括尚未正式发布且尚未正式发布的正式发布前服务 (Cloud Run Admin API v2)。借助 Config Controller,您可以使用 Kubernetes 资源模型 (KRM) 以声明方式预配 GCP 资源。Google Cloud Deploy 使用 Config Controller 在其交付流水线中创建和管理 Cloud Run 服务。

如果您有任何疑问、发现错误或想要分享反馈,请通过 clouddeploy-feedback-external@google.com 与我们联系。

Cloud Shell 教程

此外,本文档中的说明也包含在简单易学的 Cloud Shell 教程中。在使用本文档时,您可以按照该教程获取指导和背景信息。

设置环境

  1. 创建新项目,并为 Google Cloud CLI 设置默认项目。

    我们建议您从新项目着手。

    gcloud config set project PROJECT_ID
    

    在上述命令中,将 PROJECT_ID 替换为您的实际项目 ID。在本文档中,代码(命令和文件)包含 {PROJECT_ID} 作为占位符。在此处替换此值会填充本文档中的所有实例,除非您刷新页面。

  2. 启用必需的 API:

    gcloud services enable \
        krmapihosting.googleapis.com \
        clouddeploy.googleapis.com \
        compute.googleapis.com \
        run.googleapis.com
    

    此命令会启用完成此实验所需的以下 API:

    • Compute Engine
    • 配置控制器
    • Google Cloud Deploy
    • Cloud Build(通过 Google Cloud Deploy 启用)
    • Cloud Storage(通过 Google Cloud Deploy 启用)
    • Resource Manager
    • Cloud Run
    • Google Kubernetes Engine(通过 Config Controller 启用)
  3. 确保您已安装和配置 Google Cloud CLI

    此外,您还需要确保 kubectl 已安装:

    which kubectl || gcloud components install kubectl
    

    如果您是从 Cloud Shell 运行命令,则系统已经为您安装了这些组件。

  4. 配置默认的 Compute Engine 服务帐号

    默认情况下,Google Cloud Deploy 使用默认的 Compute Engine 服务帐号。该服务帐号可能已经拥有必要的权限。此步骤适用于为默认服务帐号停用自动角色授予的组织。

    运行以下命令以确保服务帐号具有适当的权限:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:$(gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)")-compute@developer.gserviceaccount.com \
        --role="roles/clouddeploy.jobRunner"
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:$(gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)")-compute@developer.gserviceaccount.com \
        --role="roles/container.developer"
    
  5. 查看 Google Cloud Deploy 概览

    本概览将帮助您了解 Google Cloud Deploy 服务和概念。

设置配置控制器

Google Cloud Deploy 使用 Config Controller 实例来部署 Cloud Run 服务和修订版本。

  1. 创建 Config Controller 之前,请确保存在默认网络:

    gcloud compute networks list
    

    成功的控制台输出将如下所示:

    NAME: default
    SUBNET_MODE: AUTO
    BGP_ROUTING_MODE: REGIONAL
    IPV4_RANGE:
    GATEWAY_IPV4:
    

    如果您没有默认网络,请运行以下命令

    gcloud compute networks create default --subnet-mode=auto
    

    如果输出正确,则无需运行此命令。

    如果您还有其他问题,请参阅 Config Controller 问题排查指南,或与组织管理员联系。

  2. 创建 Config Controller 实例。

    gcloud anthos config controller create cc-deployrun --location=us-central1
    
  1. 在要部署到的项目中授予 Config Controller 权限。以下命令提供了 Config Controller 在项目中创建和管理 Cloud Run 服务所需的最低权限。

    export SA_EMAIL="$(kubectl get ConfigConnectorContext -n config-control -o jsonpath='{.items[0].spec.googleServiceAccount}' 2> /dev/null)"
    
    gcloud projects add-iam-policy-binding "PROJECT_ID" \
        --member "serviceAccount:${SA_EMAIL}" \
        --role "roles/run.admin" \
        --project "PROJECT_ID"
    
    gcloud projects add-iam-policy-binding "PROJECT_ID" \
        --member "serviceAccount:${SA_EMAIL}" \
        --role "roles/iam.serviceAccountUser" \
        --project "PROJECT_ID"
    

创建配置文件

Google Cloud Deploy 使用 Skaffold 提供部署详细信息,以及如何为单独的目标正确部署该部署。在本实验中,我们有两个目标:run-devrun-prod

Google Cloud Deploy Cloud Run 实验目标、run-dev 和 run-prod

在本部分中,您将创建一个 skaffold.yaml 文件,该文件用于标识将通过 Google Cloud Deploy 交付流水线部署应用的 Cloud Run 清单。您还需要为 Cloud Run 服务创建清单,每个目标环境分别对应一个清单(分别是 run-dev-service.yaml 和 run-prod-service.yaml)。

  1. 为您的清单创建一个新目录,然后导航到该目录:

    mkdir deploy-cloudrun
    cd deploy-cloudrun
    
  2. 在此目录中创建 skaffold.yaml 文件。

    skaffold.yaml 会告知 Google Cloud Deploy 针对给定版本,为流水线中的每个目标部署哪些清单。

    apiVersion: skaffold/v2beta26
    kind: Config
    profiles:
     - name: prod
       deploy:
         kubectl:
           manifests:
             - run-prod-*.yaml
     - name: dev
       deploy:
         kubectl:
           manifests:
             - run-dev-*.yaml
    
  3. 在同一目录中创建 run-dev-service.yaml 文件。

    此声明式清单代表 Cloud Run 服务的 dev 环境版本。

    请注意为此环境自定义的设置,例如将容器扩缩范围限制为两个实例。标签和名称用于在项目中区分该服务版本。请注意,映像名称是一个变量:run-container,而不是特定的容器映像。当您在 Google Cloud Deploy 中创建版本时,系统会将其替换为特定的容器映像。

    apiVersion: run.cnrm.cloud.google.com/v1beta1
    kind: RunService
    metadata:
      labels:
        cloud-deploy-target: run-dev
      name: deploytest-dev
      namespace: config-control
    spec:
      ingress: INGRESS_TRAFFIC_ALL
      location: us-central1
      projectRef:
        external: projects/PROJECT_ID
      template:
        containers:
          - env:
              - name: environment
                value: dev
            image: run-container
        scaling:
          maxInstanceCount: 2
      traffic:
        - percent: 100
          type: TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST
    
  4. 在同一目录中创建 run-prod-service.yaml 文件

    此清单表示 Cloud Run 服务的 prod 版本。请注意更新后的名称、标签和扩缩设置,以及重复使用 run-container

    apiVersion: run.cnrm.cloud.google.com/v1beta1
    kind: RunService
    metadata:
      labels:
        cloud-deploy-target: run-prod
      name: deploytest-prod
      namespace: config-control
    spec:
      ingress: INGRESS_TRAFFIC_ALL
      location: us-central1
      projectRef:
        external: projects/PROJECT_ID
      template:
        containers:
          - env:
              - name: environment
                value: prod
            image: run-container
        scaling:
          maxInstanceCount: 10
      traffic:
        - percent: 100
          type: TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST
    

创建交付流水线和目标

您可以在一个文件或单独的文件中定义 Google Cloud Deploy 交付流水线和目标。在本教程中,为了简单起见,您将创建一个文件。

  1. 在包含您最近创建的清单 (/deploy-cloudrun/) 的目录中,创建 clouddeploy.yaml 文件:

    apiVersion: deploy.cloud.google.com/v1
    kind: DeliveryPipeline
    metadata:
     name: my-run-app-1
    description: main application pipeline
    serialPipeline:
     stages:
     - targetId: run-dev
       profiles:
       - dev
     - targetId: run-prod
       profiles:
       - prod
    ---
    
    apiVersion: deploy.cloud.google.com/v1
    kind: Target
    metadata:
     name: run-dev
    description: Cloud Run development environment
    gke:
     cluster: projects/PROJECT_ID/locations/us-central1/clusters/krmapihost-cc-deployrun
    ---
    
    apiVersion: deploy.cloud.google.com/v1
    kind: Target
    metadata:
     name: run-prod
    description: Cloud Run production environment
    gke:
     cluster: projects/PROJECT_ID/locations/us-central1/clusters/krmapihost-cc-deployrun
    

    cloudeploy.yaml 定义了交付流水线中两个阶段的进度序列:run-devrun-prod。该文件还为这两个阶段分别定义了目标。

    请注意,这两个目标都指向与 GKE 集群相同的 Config Controller。此 Config Controller 受创建 Config Controller 时创建的底层 GKE 集群支持,它使用其各自的清单为每个环境创建 Cloud Run 服务。

    您的 GKE 集群

  2. 向 Google Cloud Deploy 注册交付流水线和目标:

    gcloud deploy apply --file clouddeploy.yaml --region=us-central1
    

    输出将如下所示:

    Waiting for the operation on resource projects/sample-project/locations/us-central1/deliveryPipelines/my-run-app-1...done.
    Created Cloud Deploy resource: projects/sample-project/locations/us-central1/deliveryPipelines/my-run-app-1.
    Waiting for the operation on resource projects/sample-project/locations/us-central1/targets/run-dev...done.
    Created Cloud Deploy resource: projects/sample-project/locations/us-central1/targets/run-dev.
    Waiting for the operation on resource projects/sample-project/locations/us-central1/targets/run-prod...done.
    Created Cloud Deploy resource: projects/sample-project/locations/us-central1/targets/run-prod.
    

创建版本并部署容器

准备好配置文件并注册交付流水线和目标后,我们现在可以创建表示要部署的容器映像的“发布”资源。我们将使用示例容器 echoserver 进行部署:

gcloud deploy releases create run-release-001 --project=PROJECT_ID --region=us-central1 --delivery-pipeline=my-run-app-1 --labels="use-case=my-cloud-run-experiment" --images=run-container="us-docker.pkg.dev/cloudrun/container/hello"

输出将如下所示:

Creating temporary tarball archive of 4 file(s) totalling 2.0 KiB before compression.
Uploading tarball of [.] to [gs://sample-project_clouddeploy_us-central1/source/1643560782.447815-aed1fdf4973b4d25b9b7d09ff9fbbaa9.tgz]
Waiting for operation [operation-1643560782826-5d6cf50a08a8d-e40f7a45-ac4aa0ae]...done.
Created Cloud Deploy release run-release-001.
Creating rollout projects/sample-project/locations/us-central1/deliveryPipelines/my-run-app-1/releases/run-release-001/rollouts/run-release-001-to-run-dev-0001 in target run-dev...done.

由于这是第一个版本(部署到进度中的第一个目标),因此 Google Cloud Deploy 也会自动创建发布资源,并将应用部署到进度中的第一个目标 (run-dev)。您可能需要等待几分钟,直到发布完成(发布状态:SUCCEEDED)。您可以使用以下命令跟踪发布状态:

gcloud deploy rollouts list --delivery-pipeline=my-run-app-1 --region=us-central1 --release run-release-001

输出将如下所示:

approvalState: DOES_NOT_NEED_APPROVAL
createTime: '2022-02-10T21:25:11.228171Z'
deployEndTime: '2022-02-10T21:26:37.984888Z'
deployStartTime: '2022-02-10T21:26:09.778897390Z'
deployingBuild: projects/435050644073/locations/us-central1/builds/59f588d1-0cbc-4c46-9574-7e3f3b763ae6
enqueueTime: '2022-02-10T21:26:09.108240Z'
etag: 5f57d54f8b11d20e
name: projects/sample-project/locations/us-central1/deliveryPipelines/my-run-app-1/releases/run-release-001/rollouts/run-release-001-to-run-dev-0001
state: SUCCEEDED
targetId: run-dev
uid: 9cab18e1dfea4054b7d182b707c21f75

现在,该应用已部署到第一个目标,我们可以验证 Cloud Run 服务 (deploytest-dev) 是否按预期运行:

gcloud run services list --region=us-central1

输出将如下所示:


SERVICE: deploytest-dev
REGION: us-central1
URL: https://deploytest-dev-k5kzux4u6a-uc.a.run.app
LAST DEPLOYED BY: service-435050644073@gcp-sa-yakima.iam.gserviceaccount.com
LAST DEPLOYED AT: 2022-01-30T04:25:13.081829Z

提升版本

现在,应用在第一个目标 (run-dev) 中进行了部署,请使用以下命令提升应用:

gcloud deploy releases promote --release=run-release-001 --delivery-pipeline=my-run-app-1 --region=us-central1 --project=PROJECT_ID

输出将如下所示:

Promoting release run-release-001 to target run-prod.

Do you want to continue (Y/n)? Y

Creating rollout projects/sample-project/locations/us-central1/deliveryPipelines/my-run-app-1/releases/run-release-001/rollouts/run-release-001-to-run-prod-0001 in target run-prod...done.

通过 Google Cloud Console 提升版本

完成后,再次验证 Cloud Run prod 服务是否正在运行:

gcloud run services list --region=us-central1

输出将如下所示:


SERVICE: deploytest-dev
REGION: us-central1
URL: https://deploytest-dev-k5kzux4u6a-uc.a.run.app
LAST DEPLOYED BY: service-435050644073@gcp-sa-yakima.iam.gserviceaccount.com
LAST DEPLOYED AT: 2022-01-30T04:25:13.081829Z


SERVICE: deploytest-prod
REGION: us-central1
URL: https://deploytest-prod-k5kzux4u6a-uc.a.run.app
LAST DEPLOYED BY: service-435050644073@gcp-sa-yakima.iam.gserviceaccount.com
LAST DEPLOYED AT: 2022-01-30T16:04:43.468907Z

Cloud Run 服务

在 Cloud Deploy 控制台中查看结果

如需通过交付流水线查看发布进度,请打开 Google Cloud Deploy 控制台并导航到 my-run-app-1 交付流水线。

流水线可视化中的发布进度

查看版本

您可以在交付流水线详细信息视图中点击“版本”表中的相关名称 run-release-001 来查看已创建版本的详细信息。

在版本详情视图中,您可以进一步检查资源,例如指定的映像(容器)参数(build 工件)和渲染的服务清单。

版本详情

查看发布作业

每个版本也会显示在“版本”页面上。点击发布作业名称会打开发布作业详细信息,其中包含发布作业的详细信息以及渲染和部署日志。

发布详情

在 Cloud Run 控制台中查看服务

您可以使用 Cloud Run 控制台中创建的服务日志来查看服务是否已正确启动。

Cloud Run 服务日志

挑战练习

此时,您已成功创建 Cloud Run 服务交付流水线,从而将容器从开发环境提升到生产环境。下面列出了一些挑战练习,您可以进一步探索 Google Cloud Deploy 中的 Cloud Run 交付流水线。

  • 向生产服务环境的交付流水线添加批准。

  • 将您自己的现有 Cloud Run 服务转换为使用 Google Cloud Deploy 交付流水线。

  • 使用 Kustomizedevprod 参数化 Cloud Run 服务清单。(另请参阅 Google Cloud Deploy Skaffold 配置文件演示教程。)

清理

完成此实验后,您可以删除项目或移除项目中的资源,以避免这些资源的 Google Cloud 帐号产生费用。

  1. 直接从集群中删除通过 Config Controller 部署的 Cloud Run 服务。

    从 Config Controller 集群中删除命名空间可以确保删除所有创建的 Cloud Run 服务。

    kubectl -n config-control delete runservice deploytest-dev
    
    kubectl -n config-control delete runservice deploytest-prod
    
  2. 删除 Config Controller:

    gcloud anthos config controller delete cc-deployrun  --location=us-central1 --project=PROJECT_ID
    
  3. 删除交付流水线:

    gcloud deploy delivery-pipelines delete my-run-app-1 --force --region=us-central1 --project=PROJECT_ID
    

    这将删除交付流水线本身,以及 Google Cloud Deploy 为该流水线创建的所有发布和发布资源。

  4. 使用 Cloud Storage 控制台删除 Google Cloud Deploy 创建的 Cloud Storage 存储分区。

    可以使用 [PROJECT]_clouddeploy_[region][region].deploy-artifacts.[project-id].appspot.com 等命名惯例以及以下命令来标识存储分区:

    gsutil ls | egrep "_clouddeploy_|deploy-artifacts.PROJECT_ID.appspot.com" | xargs --max-lines=1 echo gsutil gsutil -m rm -r
    

    此命令将输出在您检查存储分区列表是否正确后执行的命令:

    gsutil rb gs://PROJECT_ID_clouddeploy_us-central1/
    gsutil rb gs://us-central1.deploy-artifacts.PROJECT_ID.appspot.com/