将应用 Canary 部署到目标

本快速入门介绍了如何使用 Cloud Deploy 将 Canary 部署中的示例应用映像交付给 Google Kubernetes Engine 或 Cloud Run。(您还可以将 Canary 部署到 GKE Enterprise,但本快速入门仅介绍 GKE 和 Cloud Run。)

Canary 部署会在已部署的应用版本和新版本之间分配流量。Cloud Run 会根据您在交付流水线中配置的百分比分配流量。GKE 会将新版本部署到一定比例的 pod。此快速入门首先将流量部署到 50%,然后再部署到 100%。

在本快速入门中,只有一个目标 (prod),因此我们只创建一个 GKE 集群或一个 Cloud Run 服务来运行您的应用。

在本快速入门中,您将执行以下操作:

  1. 创建一个 GKE 集群或定义一个 Cloud Run 服务。

    您也可以将 Canary 部署到 GKE Enterprise 集群,但本快速入门仅使用 GKE 和 Cloud Run。

  2. 创建 Skaffold 配置和 Kubernetes 清单以指定要部署的(预构建)容器映像。

  3. 定义 Cloud Deploy 交付流水线和部署目标

  4. 通过创建一个自动部署到一个目标的版本来调用交付流水线。

    此首个版本跳过了 Canary 阶段

  5. 在 Google Cloud 控制台中查看交付流水线和版本。

  6. 创建第二个版本,这次执行 Canary 阶段,将应用部署到 50%。

  7. 将版本推进到 100% 以进行部署。

准备工作

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Cloud Deploy, Cloud Build, GKE, Cloud Run, and Cloud Storage APIs.

    Enable the APIs

  5. Install the Google Cloud CLI.
  6. To initialize the gcloud CLI, run the following command:

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  8. Make sure that billing is enabled for your Google Cloud project.

  9. Enable the Cloud Deploy, Cloud Build, GKE, Cloud Run, and Cloud Storage APIs.

    Enable the APIs

  10. Install the Google Cloud CLI.
  11. To initialize the gcloud CLI, run the following command:

    gcloud init
  12. 如果您已安装 CLI,请确保您运行的是最新版本:

    gcloud components update
    

  13. 确保默认 Compute Engine 服务账号具有足够的权限。

    服务账号可能已经拥有必要的权限。针对默认服务账号停用自动角色授予的项目包含这些步骤。

    1. 首先添加 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/clouddeploy.jobRunner"
      

    2. 为您的特定运行时添加开发者角色。
      • 对于 GKE 和 GKE with Gateway API:

        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"
        

      • 对于 Cloud Run:

        gcloud projects add-iam-policy-binding PROJECT_ID \
            --member=serviceAccount:$(gcloud projects describe PROJECT_ID \
            --format="value(projectNumber)")-compute@developer.gserviceaccount.com \
            --role="roles/run.developer"
        

    3. 添加 iam.serviceAccountUser 角色,其中包含部署到运行时的 actAs 权限:

      gcloud iam service-accounts add-iam-policy-binding $(gcloud projects describe PROJECT_ID \
          --format="value(projectNumber)")-compute@developer.gserviceaccount.com \
          --member=serviceAccount:$(gcloud projects describe PROJECT_ID \
          --format="value(projectNumber)")-compute@developer.gserviceaccount.com \
          --role="roles/iam.serviceAccountUser" \
          --project=PROJECT_ID
      

创建运行时环境

GKE

创建一个 GKE Autopilot 集群:

 gcloud container clusters create-auto canary-quickstart-cluster \
                  --project=PROJECT_ID \
                  --region=us-central1

GKE + Gateway API

  1. 创建一个 GKE 集群,并使用推荐的设置来支持与 Istio 搭配使用:

    gcloud container clusters create canary-quickstart-cluster \
           --machine-type=n1-standard-1 \
           --num-nodes 4 \
           --region=us-central1 \
           --project=PROJECT_ID
    
  2. 获取集群凭据:

    gcloud container clusters get-credentials canary-quickstart-cluster \
           --project=PROJECT_ID \
           --region=us-central1
    
  3. 如果集群中尚不存在 Kubernetes Gateway API CRD,请安装这些 CRD。

    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.6.2/standard-install.yaml
    
  4. 安装 Istio 以启用 Istio 的网关控制器实现。

    curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.2 sh - \
    && ./istio-1.17.2/bin/istioctl install --set profile=minimal -y
    

Cloud Run

如果您使用的是 Cloud Run,则可以跳过此命令,无需在此处执行任何操作。

准备 Skaffold 配置和应用清单

Cloud Deploy 使用 Skaffold 提供要部署的内容的详细信息,以及如何将其正确部署到目标

在本快速入门中,您将创建一个 skaffold.yaml 文件,以标识要部署的 Kubernetes 清单或 Cloud Run 服务配置。

  1. 打开一个终端窗口。

  2. 创建一个新目录,并导航至该目录。

    GKE

    mkdir deploy-canary-quickstart-gke
    cd deploy-canary-quickstart-gke
    

    GKE + Gateway API

    mkdir deploy-canary-quickstart-gke-gatewayapi
    cd deploy-canary-quickstart-gke-gatewayapi
    

    Cloud Run

    mkdir deploy-canary-quickstart-run
    cd deploy-canary-quickstart-run
    
  3. 创建名为 skaffold.yaml 且包含以下内容的文件:

    GKE

    apiVersion: skaffold/v4beta7
    kind: Config
    manifests:
      rawYaml:
      - kubernetes.yaml
    deploy:
      kubectl: {}
    

    GKE + Gateway API

    apiVersion: skaffold/v4beta7
    kind: Config
    manifests:
      rawYaml:
      - kubernetes.yaml
    deploy:
      kubectl: {}
    

    Cloud Run

    apiVersion: skaffold/v4beta7
    kind: Config
    manifests:
      rawYaml:
      - run.yaml
    deploy:
      cloudrun: {}
    

    此文件是一个最小型的 Skaffold 配置,用于标识清单。在本快速入门中,您将创建该文件。不过,对于简单的非生产应用,您也可以让 Cloud Deploy 为您创建一个

    如需详细了解此文件,请参阅 skaffold.yaml 参考文档

  4. 创建应用清单。

    GKE

    deploy-canary-quickstart-gke 目录中创建一个名为 kubernetes.yaml 的文件,其中包含以下内容:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment
      labels:
        app: my-app
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-app
      template:
        metadata:
          labels:
            app: my-app
        spec:
          containers:
          - name: nginx
            image: my-app-image
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      namespace: default
    spec:
      selector:
        app: my-app
      ports:
        - protocol: TCP
          port: 80
    

    此文件是一个 Kubernetes 清单,用于应用到集群以部署应用。此清单包含 Canary 部署所需的服务和部署资源,以及使用 Gateway API 所需的 HTTPRoute 和网关资源。

    此处将要部署的容器映像设置为占位符 my-app-image,在您创建版本时,系统会将其替换为特定映像。

    GKE + Gateway API

    deploy-canary-quickstart-gke-gatewayapi 目录中创建一个名为 kubernetes.yaml 的文件,其中包含以下内容:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: my-gateway
      annotations:
        networking.istio.io/service-type: "ClusterIP"
    spec:
      gatewayClassName: istio
      listeners:
      - name: default
        hostname: "*.example.com"
        port: 80
        protocol: HTTP
        allowedRoutes:
          namespaces:
            from: All
    ---
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: my-httproute
    spec:
      parentRefs:
      - kind: Gateway
        name: my-gateway
      hostnames:
      - "test.example.com"
      rules:
      - backendRefs:
        - name: my-service
          port: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      selector:
        app: my-app
      ports:
      - name: tcp-port
        protocol: TCP
        port: 80
        targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment
      labels:
        app: my-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-app
      template:
        metadata:
          labels:
            app: my-app
        spec:
          containers:
          - name: nginx
            image: my-app-image
    

    此文件是一个 Kubernetes 清单,用于应用到集群以部署应用。此清单包含 Canary 部署所需的服务和部署资源,以及使用 Gateway API 所需的 HTTPRoute 和网关资源。

    此处将要部署的容器映像设置为占位符 my-app-image,在您创建版本时,系统会将其替换为特定映像。

    Cloud Run

    deploy-canary-quickstart-run 目录中创建一个名为 run.yaml 的文件,其中包含以下内容:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: my-canary-run-service
    spec:
      template:
        spec:
          containers:
          - image: my-app-image
    

    此文件是一个基本的 Cloud Run 服务定义,会在部署时应用,以便在 Cloud Run 中创建您的服务。此处将要部署的容器映像设置为占位符 my-app-image,该占位符会在您创建版本时替换为具体映像。

创建交付流水线和目标

您可以在一个文件中或在单独的文件中定义交付流水线和目标。在本快速入门中,我们将为流水线和单个目标创建一个文件:

GKE

deploy-canary-quickstart-gke 目录中创建一个名为 clouddeploy.yaml 的文件,其中包含以下内容:

apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
  name: my-canary-demo-app-1
description: main application pipeline
serialPipeline:
  stages:
  - targetId: prod
    profiles: []
    strategy:
      canary:
        runtimeConfig:
          kubernetes:
            serviceNetworking:
              service: "my-service"
              deployment: "my-deployment"
        canaryDeployment:
          percentages: [50]
          verify: false
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
  name: prod
description: prod GKE cluster
gke:
 cluster: projects/PROJECT_ID/locations/us-central1/clusters/canary-quickstart-cluster

GKE + Gateway API

deploy-canary-quickstart-gke-gatewayapi 目录中创建一个名为 clouddeploy.yaml 的文件,其中包含以下内容:

apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
  name: my-canary-demo-app-1
description: main application pipeline
serialPipeline:
  stages:
  - targetId: prod
    profiles: []
    strategy:
      canary:
        runtimeConfig:
          kubernetes:
            gatewayServiceMesh:
              httpRoute: "my-httproute"
              service: "my-service"
              deployment: "my-deployment"
        canaryDeployment:
          percentages: [50]
          verify: false
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
  name: prod
description: prod GKE cluster
gke:
 cluster: projects/PROJECT_ID/locations/us-central1/clusters/canary-quickstart-cluster

Cloud Run

deploy-canary-quickstart-run 目录中创建一个名为 clouddeploy.yaml 的文件,其中包含以下内容:

apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
  name: my-canary-demo-app-1
description: main application pipeline
serialPipeline:
  stages:
  - targetId: prod
    profiles: []
    strategy:
      canary:
        runtimeConfig:
          cloudRun:
            automaticTrafficControl: true
        canaryDeployment:
          percentages: [50]
          verify: false
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
  name: prod
description: prod Run Service
run:
  location: projects/PROJECT_ID/locations/us-central1
  1. 在 Cloud Deploy 服务中注册流水线和目标:

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

    现在,您已经有了包含一个目标的流水线,该目标配置了 Canary 部署策略。

  2. 确认您的流水线和目标:

    在 Google Cloud 控制台中,前往 Cloud Deploy 交付流水线页面,查看可用交付流水线的列表。

    打开“交付流水线”页面

    此时将显示您刚刚创建的交付流水线,并且目标列会列出了您配置的一个目标。

    Google Cloud 控制台中的交付流水线直观显示

创建版本

版本是表示要部署的更改的中央 Cloud Deploy 资源。交付流水线定义该版本的生命周期。如需详细了解该生命周期,请参阅 Cloud Deploy 服务架构

如需创建表示要部署的容器映像的 release 资源,请从 deploy-canary-quickstart-gkedeploy-canary-quickstart-gke-gatewayapideploy-canary-quickstart-run 目录运行以下命令:

GKE

 gcloud deploy releases create test-release-001 \
   --project=PROJECT_ID \
   --region=us-central1 \
   --delivery-pipeline=my-canary-demo-app-1 \
   --images=my-app-image=gcr.io/google-containers/nginx@sha256:f49a843c290594dcf4d193535d1f4ba8af7d56cea2cf79d1e9554f077f1e7aaa

GKE + Gateway API

 gcloud deploy releases create test-release-001 \
   --project=PROJECT_ID \
   --region=us-central1 \
   --delivery-pipeline=my-canary-demo-app-1 \
   --images=my-app-image=gcr.io/google-containers/nginx@sha256:f49a843c290594dcf4d193535d1f4ba8af7d56cea2cf79d1e9554f077f1e7aaa

Cloud Run

 gcloud deploy releases create test-release-001 \
   --project=PROJECT_ID \
   --region=us-central1 \
   --delivery-pipeline=my-canary-demo-app-1 \
   --images=my-app-image=us-docker.pkg.dev/cloudrun/container/hello@sha256:4a856b6f1c3ce723a456ddc2adfbb794cbfba93f727e2d96fcf6540bd0d6fff4

请注意 --images= 标志,您可以使用该标志将清单或服务定义中的占位符 (my-app-image) 替换为经过 SHA 认证的特定映像。Google 建议您以这种方式将清单模板化,并在创建版本时使用经过 SHA 限定的映像名称。

当您创建版本时,Cloud Deploy 还会自动创建一个发布资源,以便立即部署到您的一个目标 prod

我们跳转到稳定阶段

对于此首次发布版本,我们会跳过 Canary 阶段,并部署到 100%(稳定阶段)。这是因为应用之前未部署,因此无法计算 50% 的 Pod(对于 GKE)或服务的流量分配方式(对于 Cloud Run)。Pod (GKE) 或修订版 (Cloud Run) 尚不存在。

跳过了 Canary 版阶段后,我们现在可以开始稳定版阶段了,届时流量将达到 100%。然后,我们将创建另一个版本,该版本将执行 Canary 版本。

在实际情况下,您通常会在应用已在运行的情况下执行 Canary 部署,因此很少会跳过此阶段。

在 Google Cloud 控制台中查看版本

现在,您已创建第一个版本,发布流程也已创建,您可以在 Google Cloud 控制台中查看该版本和发布流程。您还可以查看流水线直观显示效果,其中会显示版本的当前状态。

  1. 在 Google Cloud 控制台中,前往 Cloud Deploy 交付流水线页面,查看您的 my-canary-demo-app-1 交付流水线。

    打开“交付流水线”页面

  2. 点击交付流水线的名称“my-canary-demo-app-1”。

    流水线直观显示将显示应用的部署状态。由于流水线中只有一个阶段,因此可视化结果中只会显示一个节点。

    Google Cloud 控制台中的交付流水线直观显示

    您的版本列在版本标签页中交付流水线详细信息下。

  3. 点击版本名称 test-release-001

    您的发布会显示在发布下。您可以点击发布以查看其详细信息,包括部署日志。

    Google Cloud 控制台中的发布

    请注意,发布状态为“待推进”,并且流水线可视化图中显示的目标包含指向“推进到稳定版”的链接。

推进发布阶段

在首次发布后,系统跳过了 Canary 版阶段,发布流程正在等待开始“稳定版”阶段,该阶段会将应用部署到 100% 的用户:

  1. 在流水线直观显示中,点击升级到稳定版

  2. 出现提示时,点击Advance以确认。

几分钟后,该发布流程现已进入“稳定”阶段,并且应用已 100% 部署完毕。

处于稳定阶段的交付流水线

执行 Canary 部署

由于第一个版本跳过了 Canary 阶段,我们现在将创建另一个版本,这次将执行 Canary 部署。

  1. 如需创建新的 release,请从 deploy-canary-quickstart-gkedeploy-canary-quickstart-gke-gatewayapideploy-canary-quickstart-run 目录中运行以下命令:

    GKE

    gcloud deploy releases create test-release-002 \
      --project=PROJECT_ID \
      --region=us-central1 \
      --delivery-pipeline=my-canary-demo-app-1 \
      --images=my-app-image=gcr.io/google-containers/nginx@sha256:f49a843c290594dcf4d193535d1f4ba8af7d56cea2cf79d1e9554f077f1e7aaa
    

    GKE + Gateway API

    gcloud deploy releases create test-release-002 \
      --project=PROJECT_ID \
      --region=us-central1 \
      --delivery-pipeline=my-canary-demo-app-1 \
      --images=my-app-image=gcr.io/google-containers/nginx@sha256:f49a843c290594dcf4d193535d1f4ba8af7d56cea2cf79d1e9554f077f1e7aaa
    

    Cloud Run

    gcloud deploy releases create test-release-002 \
      --project=PROJECT_ID \
      --region=us-central1 \
      --delivery-pipeline=my-canary-demo-app-1 \
      --images=my-app-image=us-docker.pkg.dev/cloudrun/container/hello@sha256:4a856b6f1c3ce723a456ddc2adfbb794cbfba93f727e2d96fcf6540bd0d6fff4
    

    几分钟后,系统会创建一个发布版本,这次会执行 Canary 阶段:

    交付流水线开始 Canary 版阶段

    第一个发布阶段完成后,发布即进入 Canary 版阶段:

    Google Cloud 控制台中的交付流水线直观显示,其中应用部署进度为 50%

    这意味着,应用目前已部署到 50%。对于基于 serviceNetworking 的 GKE,它会部署到一半的 pod。对于基于 Gateway API 的 GKE 和 Cloud Run 流量,分配比例为 50%。

  2. 点击提前发布,然后在出现提示时点击提前

    这会将发布阶段推进到“稳定”阶段,将应用部署到 100%。

    处于稳定阶段且已部署到 100% 的交付流水线

清理

为避免因本页中使用的资源导致您的 Google Cloud 账号产生费用,请按照以下步骤操作。

  1. 删除 canary-quickstart-cluster 集群(仅限 GKE):

    gcloud container clusters delete canary-quickstart-cluster --region=us-central1 --project=PROJECT_ID
    
  2. 删除 my-canary-run-service 服务(仅限 Cloud Run):

    gcloud run services delete my-canary-run-service --region=us-central1 --project=PROJECT_ID
    
  3. 删除交付流水线、目标以及所有版本和发布资源:

    gcloud deploy delete --file=clouddeploy.yaml --force --region=us-central1 --project=PROJECT_ID
    
  4. 删除 Cloud Deploy 创建的 Cloud Storage 存储分区。

    一个以 _clouddeploy 结尾,另一个是 [region].deploy-artifacts.[project].appspot.com

    打开“Cloud Storage 浏览器”页面

恭喜,您已经完成快速入门!

后续步骤