将应用以 Canary 方式部署到目标

本快速入门介绍了如何使用 Cloud Deploy 以 Canary 部署方式将示例应用映像交付给 Google Kubernetes Engine 或 Cloud Run。 (您也可以向 GKE Enterprise 运行 Canary 部署,但此快速入门中仅显示了 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. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  7. To initialize the gcloud CLI, run the following command:

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

    Go to project selector

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

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

    Enable the APIs

  11. Install the Google Cloud CLI.

  12. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  13. To initialize the gcloud CLI, run the following command:

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

    gcloud components update
    

  15. 确保默认 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 和使用 Gateway API 的 GKE:

        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,请安装它们。

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

      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 清单,应用于集群以部署应用。此清单包含灰度部署所需的 Service 和 Deployment 资源,以及使用 Gateway API 所需的 HTTPRoute 和 Gateway 资源。

    要部署的容器映像在此处设置为占位符 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 清单,应用于集群以部署应用。此清单包含灰度部署所需的 Service 和 Deployment 资源,以及使用 Gateway API 所需的 HTTPRoute 和 Gateway 资源。

    要部署的容器映像在此处设置为占位符 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:95ade4b17adcd07623b0a0c68359e344fe54e65d0cb01b989e24c39f2fcd296a

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

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

我们跳到稳定阶段

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

跳过 Canary 阶段后,我们现在准备开始稳定阶段,该阶段会将流量增加到 100%。之后,我们将创建另一个版本,并执行 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 控制台中的发布

    请注意,发布状态为“Pending advance”,并且流水线可视化图表中显示的目标具有指向“Advance to stable”的链接。

推进发布阶段

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

  1. 在流水线可视化视图中,点击推进到稳定版

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

几分钟后,发布进入“稳定”阶段,应用部署到 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:95ade4b17adcd07623b0a0c68359e344fe54e65d0cb01b989e24c39f2fcd296a
    

    几分钟后,系统会创建一个发布版本,这次会执行 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 浏览器”页面

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

后续步骤