使用 Canary 部署策略

本文档介绍了如何配置和使用 Canary 部署策略。

什么是 Canary 部署?

Canary 部署是一种应用的渐进式发布方式,它会在已部署的版本和新版本之间拆分流量,先面向部分用户发布,然后再全面发布。

支持的目标类型

Cloud Deploy 中的 Canary 部署支持所有目标类型,包括:

Canary 还支持多目标

为什么要使用 Canary 部署策略?

借助 Canary 部署,您可以部分发布应用。在 这样,您就可以先确保新版应用可靠,然后再 则将其分发给所有用户。

如果您要部署到 GKE 或 GKE Enterprise 您需要将应用的新版本部署到 Pod 数量旧版本会继续运行,但会将更多流量发送到新 pod。

如果您要部署到 Cloud Run,Cloud Run 本身会根据您配置的百分比,在旧修订版本和新修订版本之间拆分流量。

Canary 的类型

借助 Cloud Deploy,您可以配置以下类型的 Canary 部署:

  • 自动

    使用 自动化 Canary 版 你可以为 Cloud Deploy 配置一系列 表示渐进式部署的百分比。Cloud Deploy 代表您执行其他操作,以分配流量 百分比。

  • 自定义自动化

    对于自定义自动化 Canary,您可以提供以下信息:

    • 阶段名称
    • 百分比目标
    • 要用于相应阶段的 Skaffold 配置文件
    • 是否包含验证作业
    • 是否包含部署前作业和/或部署后作业

    不过,您无需提供流量平衡信息;Cloud Deploy 会创建必要的资源。

  • 自定义

    借助自定义 Canary,您可以单独配置每个 Canary 阶段, 包括:

    • 阶段名称
    • 百分比目标
    • 要用于相应阶段的 Skaffold 配置文件
    • 是否包含验证作业
    • 是否包含部署前作业和/或部署后作业

    此外,对于完全自定义的 Canary 版,您需要提供 流量平衡配置 此处

Canary 部署的阶段

为 Canary 部署创建版本时,系统会为每个 Canary 增量创建一个阶段,并为最终的 100% 创建一个 stable 阶段。

例如,如果您将 Canary 配置为按 25%、50% 和 75% 递增,则该发布将分为以下阶段:

  • canary-25
  • canary-50
  • canary-75
  • stable

如需详细了解发布阶段、作业和作业运行,请参阅 管理发布

在自动化或自定义自动化 Canary 期间会发生什么

为了支持 Canary 部署,Cloud Deploy 在呈现 Kubernetes 清单或 Cloud Run 服务配置时会包含特殊的处理步骤:

GKE/Enterprise

这里展示了 Cloud Deploy 如何在 基于网络的 GKE 和 GKE Enterprise:

  1. 您需要提供部署资源和服务资源的名称。

  2. Cloud Deploy 会创建一个额外的 Deployment 资源, 当前 Deployment 的名称加上 -canary

  3. Cloud Deploy 会修改该服务,以调整选择器以选择当前部署中的 Pod 和 Canary Pod。

    Cloud Deploy 会根据此处所述的计算方法,计算要为 Canary 使用 Pod 的数量。此计算会因您启用或停用 Pod 过度配置而有所不同。

    如果我们跳转到 stable 阶段,Cloud Deploy 会添加要用于匹配 Pod 的标签,以便这些标签可供后续 Canary 版运行使用。

    Cloud Deploy 会创建一个包含特定于阶段的 pod 百分比的部署,并针对每个阶段进行更新。具体方法是将 Pod 数量作为原始 Pod 数量的百分比进行计算。这可能会导致流量分配不精确。如果您需要精确的流量分配,可以使用 Gateway API 来实现。

    此外,系统还会复制 Secret 和 ConfigMap,并将其重命名为 -canary

  4. stable 阶段,-canary Deployment 会缩减至 将原始 Deployment 替换为新的 Deployment

    Cloud Deploy 不会修改原始 Deployment,直到 stable 阶段。

Cloud Deploy 会预配 pod,以尽可能接近所请求的 Canary 版百分比。此值取决于 Pod 数量,而不是 Pod 的流量。如果您希望基于流量运行 Canary 版, 需要使用 Gateway API

对于基于 GKE 网络的 Canary 版,您可以启用或停用 Pod 过度配置。以下部分介绍了 Cloud Deploy 如何计算每个 Canary 阶段要为 Canary 部署预配的 pod 数量。

启用了超量预配的 Pod 预配

启用过度配置 (disablePodOverprovisioning: false) 后,Cloud Deploy 会根据运行现有部署的 pod 数量,创建足够多的额外 pod 来运行您所需的 Canary 版百分比。以下公式展示了 Cloud Deploy 会计算要为 Pod 预配的 Pod 数量 Canary 部署(当 Pod 超额预配时) 已启用:

math.Ceil( percentage * ReplicaCountOfDeploymentOnCluster / (100-percentage))

根据此公式,当前副本数量(在该 Canary 版之前您已有的 pod 数量)乘以相应阶段的 Canary 版百分比,然后将结果除以(100 减去该百分比)。

例如,如果您已有 4 个 pod,并且 Canary 阶段为 50%,则 Canary pod 的数量为 4。(100-percentage 的结果用作百分比:100-50=50,视为 .50。)

默认行为是过度预配 Pod。

停用超额预配功能时的 Pod 预配

您可以停用过度配置 (disablePodOverprovisioning: true),以确保 Cloud Deploy 不会增加副本数量。

以下公式展示了在停用 Pod 过度预配的情况下,Cloud Deploy 如何为每个 Canary 阶段计算 Canary 部署的 Pod 预配:

math.Ceil( (ReplicaCountOfDeploymentOnCluster + ReplicaCountOfCanaryDeploymentOnCluster) * percentage)

在此公式中,只有在已经有 Canary 阶段时,ReplicaCountOfCanaryDeploymentOnCluster 才会存在。如果这是第一个 Canary 阶段,则没有 ReplicaCountOfCanaryDeploymentOnCluster

如果从 4 个 Pod 开始,该数字将乘以 Canary 百分比 (例如 50% 或 .5),以获得 2。原始部署现在变成了 缩减为 2 个 Pod,并且为 Canary 部署创建了 2 个新 Pod。如果您将 Canary 阶段的比例设为 75%,则有 2(原始部署)+2(第一个 Canary 阶段)*.75,以便获得运行 3 Canary Pod 和 1 Pod 的原始部署。

网关 GKE/企业版

这里展示了 Cloud Deploy 如何在 使用 Gateway API 的 GKE 和 GKE Enterprise:

  1. 除了部署和服务引用之外,您还需要提供一个 HTTPRoute 资源,其中包含引用服务的 backendRefs 规则。

  2. Cloud Deploy 会创建一个新的部署,其名称为原始部署名称加上 -canary,并创建一个新的服务,其名称为原始服务名称加上 -canary

    此外,系统还会复制并使用 -canary 重命名 Secret、ConfigMap 和横向 Pod 自动扩缩器。

  3. 对于每个 Canary 阶段,Cloud Deploy 都会修改 HTTPRoute,以根据相应阶段的百分比更新原始部署的 pod 和 Canary 部署的 pod 之间的权重。

    因为在将更改传播到 HTTPRoute 时可能会有延迟 您可以 routeUpdateWaitTime属性包含在您的 配置,因此系统会在完成更新后等待指定时间 传播。

  4. stable 阶段,-canary 部署会缩减为零,原始部署会更新为使用新版本的部署。

    此外,HTTPRoute 现在已恢复为您提供的原始路由。

    Cloud Deploy 不会修改原始 Deployment 或 服务直至 stable 阶段。

Cloud Run

Cloud Deploy 按照以下方式执行 Canary 部署: Cloud Run:

  • 对于到 Cloud Run 的 Canary 部署,请不要提供 您的服务 YAML 中的 traffic

  • 为 Canary 版本创建新的发布版本时,Cloud Deploy 会在 Cloud Deploy 成功部署的先前修订版本和新修订版本之间拆分流量。

如果您想要了解 Canary 部署的各个阶段之间的差异, 您可以在 版本检查器。您甚至可以在发布之前执行此操作。此外,如果您使用的是 并行部署,还可以检查每个子级的 呈现的清单。

配置 Canary 部署

本部分介绍如何为 Cloud Storage 存储分区配置交付流水线和目标, Canary 部署

此处的说明仅包含特定于 Canary 配置的内容。通过 部署您的应用一文中介绍了 有关如何配置和执行部署流水线的一般说明。

确保您拥有所需的权限

除了使用 Cloud Deploy 所需的其他 Identity and Access Management 权限之外,您还需要具备以下权限,才能执行 Canary 部署可能需要的其他操作:

  • clouddeploy.rollouts.advance
  • clouddeploy.rollouts.ignoreJob
  • clouddeploy.rollouts.cancel
  • clouddeploy.rollouts.retryJob
  • clouddeploy.jobRuns.get
  • clouddeploy.jobRuns.list
  • clouddeploy.jobRuns.terminate

如需详细了解哪些可用角色包含这些权限,请参阅 IAM 角色和权限

准备 skaffold.yaml

与标准部署一样,您的 Canary 版需要 skaffold.yaml 文件, 定义了清单和服务定义如何呈现和部署。

除了标准部署所需的条件之外,您为 Canary 部署创建的 skaffold.yaml 没有任何特殊要求。

准备清单或服务定义

与标准部署一样,您的 Canary 版本需要 Kubernetes 清单或 Cloud Run 服务定义。

GKE 和 GKE Enterprise

对于 Canary,您的清单必须包含以下内容:

  • 一个部署一个服务。

  • Service 必须定义选择器,并且该选择器必须选择 Pod 所有资源默认值为 app

  • 如果您使用的是基于 Gateway API 的 Canary 版本,则清单还必须包含 HTTPRoute

Cloud Run

对于 Cloud Run 上的 Canary 版 使用 Cloud Run 服务定义文件就足够了 没有 traffic 节。Cloud Deploy 会为您管理在上一个成功的修订版本和新修订版本之间拆分流量。

配置自动化 Canary

以下说明适用于 Cloud Run 以及基于 GKE 和 GKE Enterprise 服务的网络目标。如果您要将 Kubernetes Gateway API 与 GKE 或 GKE Enterprise,请参阅此文档

您可以在交付流水线定义中配置自动化 Canary:

GKE 和 GKE Enterprise

在流水线阶段,添加 strategy 属性,如下所示:

serialPipeline:
  stages:
  - targetId: prod
    profiles: []
    strategy:
      canary:
        runtimeConfig:
          kubernetes:
            serviceNetworking:
              service: "SERVICE_NAME"
              deployment: "DEPLOYMENT_NAME"
              podSelectorLabel: "LABEL"
        canaryDeployment:
          percentages: [PERCENTAGES]
          verify: true|false
          predeploy:
            actions: "PREDEPLOY_ACTION"
          postdeploy:
            actions: "POSTDEPLOY_ACTION"

在此配置中...

  • SERVICE_NAME 是 Kubernetes Service 的名称, 。

  • DEPLOYMENT_NAME 是您的 Kubernetes 部署的名称,在清单中定义。

  • LABEL 是 Pod 选择器标签。此值必须与标签相符 选择器。这项设置为可选设置。默认值为 app

  • PERCENTAGES 是表示 Canary 增量百分比值的逗号分隔列表,例如 [5, 25, 50]

    此外,这不包括 100,因为 100% 部署 假设在 Canary 中,并由 stable 阶段

  • 您可以启用部署验证 (verify: true).如果您这样做,系统会在每个阶段启用 verify 作业。

  • PREDEPLOY_ACTION

    与您在 skaffold.yaml 中用于定义要在部署前运行的自定义操作的 ACTION_NAME 相同。

  • POSTDEPLOY_ACTION

    与您在ACTION_NAME skaffold.yaml 来定义要在之后运行的自定义操作 部署。

Cloud Run

在流水线阶段,添加 strategy 属性,如下所示:

serialPipeline:
  stages:
  - targetId: prod
    profiles: []
    strategy:
      canary:
        runtimeConfig:
          cloudRun:
            automaticTrafficControl: true
        canaryDeployment:
          percentages: [PERCENTAGES]
          verify: true|false
          predeploy:
            actions: "PREDEPLOY_ACTION"
          postdeploy:
            actions: "POSTDEPLOY_ACTION"

在此配置中...

  • PERCENTAGES 是以英文逗号分隔的百分比列表 表示 Canary 增量的值,例如 [25, 50, 75]。请注意,这不包括 100,因为在 Canary 版中假定已 100% 部署,并且由 stable 阶段处理。

  • 您可以启用部署验证 (verify: true)。如果您这样做,系统会向每个 Canary 阶段添加一个 verify 作业。

  • PREDEPLOY_ACTION

    与您在 skaffold.yaml 中用于定义要在部署前运行的自定义操作的 ACTION_NAME 相同。

  • POSTDEPLOY_ACTION

    与您在ACTION_NAME skaffold.yaml,用于定义要在之后运行的自定义操作 部署。

配置自定义 Canary

您可以手动配置 Canary 版本,而不是完全依赖于 Cloud Deploy 提供的自动化功能。使用自定义 Canary 配置时,您需要在交付流水线定义中指定以下内容:

  • 发布阶段名称

    在完全自动化的 Canary 版中,Cloud Deploy 会为您命名各个阶段(例如 canary-25canary-75stable)。不过,对于自定义 Canary 版,您可以为每个阶段指定任何名称,只要该名称在该 Canary 版阶段的所有阶段中都是唯一的,并且符合资源名称限制即可。但最后一个 (100%) 阶段名称必须为 stable

  • 每个阶段的百分比目标

    请为每个阶段单独指定百分比。

  • 要用于相应阶段的 Skaffold 配置文件

    您可以为每个阶段使用单独的 Skaffold 配置文件,也可以使用相同的配置文件,或者任意组合。每个配置文件可以使用不同的 Kubernetes 清单 或 Cloud Run 服务定义您还可以为给定阶段使用多个配置文件。Cloud Deploy 将它们组合在一起。

  • 此阶段是否有验证作业

    请注意,如果您要启用验证功能,还需要配置 skaffold.yaml 以进行验证。

  • 相应阶段是否有部署前作业或部署后作业

    如果您要启用部署前作业或部署后作业,则需要为这些作业配置 skaffold.yaml

自定义 Canary 支持所有目标类型

自定义 Canary 配置元素

以下 YAML 显示了完全自定义 Canary 部署各个阶段的配置:

strategy:
  canary:
    # Custom configuration for each canary phase
    customCanaryDeployment:
      phaseConfigs:
      - phaseId: "PHASE1_NAME"
        percentage: PERCENTAGE1
        profiles: [ "PROFILE_NAME" ]
        verify: true | false
        predeploy:
          actions: "PREDEPLOY_ACTION"
        postdeploy:
          actions: "POSTDEPLOY_ACTION"
      - 
      - phaseId: "stable"
        percentage: 100
        profiles: [ "LAST_PROFILE_NAME" ]
        verify: true|false
        predeploy:
          actions: "PREDEPLOY_ACTION"
        postdeploy:
          actions: "POSTDEPLOY_ACTION"

在以下 YAML 中

  • PHASE1_NAME

    是相应阶段的名称。每个阶段名称都必须是唯一的。

  • [ "PROFILE_NAME" ]

    是要为相应阶段使用的配置文件的名称。您可以为每个阶段使用相同的配置文件,也可以为每个阶段使用不同的配置文件,还可以任意组合使用。此外,您还可以 指定多个配置文件。Cloud Deploy 会使用您指定的所有配置文件,以及整个阶段使用的配置文件或清单。

  • stable

    最终阶段必须命名为 stable

  • PERCENTAGE1

    是第一阶段要部署的百分比。每个阶段必须具有唯一的 百分比值,并且该值必须是整数(对于 10.5, 示例),且阶段必须按升序排列。

  • verify: true|false

    告知 Cloud Deploy 是否应为相应阶段添加验证作业。请注意,对于要使用“验证”的每个阶段,Skaffold 都会为该阶段的“验证”使用为该阶段的“渲染”和“部署”指定的配置文件。

  • PREDEPLOY_ACTION

    与您在ACTION_NAME skaffold.yaml,用于定义要在部署之前运行的自定义操作。

  • POSTDEPLOY_ACTION

    与您在 skaffold.yaml 中用于定义要在部署后运行的自定义操作的 ACTION_NAME 相同。

最后一个阶段的百分比必须为 100。各阶段根据 它们的顺序与您在此 ​customCanaryDeployment 节中配置它们的顺序相同,但如果 百分比值并非按升序排列,则 注册交付流水线 失败并显示错误。

请注意,自定义 Canary 的配置不包含 runtimeConfig 节。如果您添加了 runtimeConfig,则系统会将其视为自定义自动化 Canary 版本

配置自定义自动化 Canary

自定义自动化 Canary 与自定义 Canary 类似 因为您指定了单独的 Canary 阶段 并采用自定义阶段名称 百分比值、Skaffold 配置文件、验证作业以及部署前和部署后 作业。但使用自定义 Canary 时,您无需提供 配置 (定义流量分配)Cloud Deploy 会执行 但您仍然需要提供 Skaffold 配置文件 每个阶段使用的值

如需配置自定义自动化 Canary,请添加 runtimeConfig 诗节(如此处所示),并添加 customCanaryDeployment 诗节(如此处所示)。

使用 Kubernetes Gateway API 服务网格配置 Canary 部署

虽然您可以使用 Cloud Deploy Canary 部署 将您的应用部署到基于 Kubernetes 服务的网络中, 另一种方法是使用 Kubernetes Gateway API 服务网格。 本部分介绍了具体方法。

您可以将 Gateway API 与 Istio 或任何受支持的实现搭配使用。

  1. 设置 Gateway API 资源:

    以上仅为示例。

  2. 在 Kubernetes 清单中,当您执行以下操作时提供给 Cloud Deploy : 创建版本时,添加以下内容:

    • HTTPRoute 引用您的网关资源的

    • 部署

    • 服务

  3. 配置交付流水线以及要将 Canary 部署到其上的目标:

    • 目标的配置与任何目标的配置相同。

    • 交付流水线配置,在 包括一个 gatewayServiceMesh 节,用于引用您的 Kubernetes Gateway API HTTPRoute 配置以及您的 Deployment 和 Service。

      strategy:
       canary:
         runtimeConfig:
           kubernetes:
             gatewayServiceMesh:
               httpRoute: "ROUTE"
               service: "SERVICE"
               deployment: "DEPLOYMENT"
               routeUpdateWaitTime: "WAIT_TIME"
               podSelectorLabel: "LABEL"
         canaryDeployment:
           percentages:
           - 50
      

      其中...

      • ROUTE 是 httpRoute 配置,用于定义所需的路由行为。

      • SERVICE 是您的 Service 配置, Canary 部署需要 GKE 和 GKE Enterprise

      • DEPLOYMENT 是您的 Deployment 配置, Canary 部署需要 GKE 和 GKE Enterprise

      • WAIT_TIME 是 Cloud Deploy 部署到 等待对 HTTPRoute 资源的更改完成传播, 避免丢弃请求例如:routeUpdateWaitTime: 60s

        如果您使用 Gateway API 在没有 Istio 的情况下运行 Canary 版,并且 Gateway API 连接到 Google Cloud 负载均衡器,则在缩减 Canary 版实例时可能会丢失少量流量。您可以 如果您观察到此行为,请配置此设置。

      • LABEL 是 Pod 选择器标签。此标签必须与清单中定义的 Kubernetes 服务和部署中的标签选择器相匹配。您可以选择是否创建 PIN 码。默认值为 app

将并行部署与 Canary 部署策略搭配使用

您可以使用并行部署来运行 Canary 部署。 这意味着要逐步部署到的目标可以包含两个或更多个目标 子目标。例如,您可以逐步部署到 多个区域。

并行 Canary 版与单目标 Canary 版有何不同

  • 与单目标 Canary 部署一样 您需要一个 Kubernetes Deployment 配置 在清单中添加 Kubernetes Service 配置

  • 与单目标 Canary 部署一样,您的交付流水线配置必须在适用阶段的阶段定义中包含 strategy.canary 诗节。

  • 此外,您还需要 配置多目标 您需要 配置子级目标 多目标引用的标识符

  • 当您创建版本时,系统会进行控制器发布 以及子发布

    这两种类型的发布(控制组和子组)都针对所有配置的 Canary 百分比设置了单独的阶段,并针对 100% 的 Canary 设置了 stable 阶段。

  • 您无法继续 子发布

    您只能推进控制器发布。推进控制器时 子发布也会提前 Cloud Deploy。

  • 您无法重试 失败的作业数。

    您只能在子发布中重试作业。

  • 您无法在控制器发布中忽略失败的作业。

    您只能忽略子发布中的失败作业。

  • 您可以取消控制器发布、 但无法取消子发布。

  • 您只能在子发布(而非控制器发布)下终止作业运行

如果 Canary 版中并行发布失败,该怎么办

当子发布失败时,控制器发布可能会转换到不同的状态,具体取决于子发布的具体情况:

  • 一个或多个子发布失败,但至少有一个子发布仍处于 IN_PROGRESS 时,控制器发布保持 IN_PROGRESS

  • 如果一项或多项子发布失败,但至少有一项子发布成功,并且当前阶段后面还有其他阶段,则控制器发布状态为 HALTED

    如果这是 stable 阶段,则控制器发布为 FAILED

    HALTED为您提供了 ignore重试 失败的子发布中失败的作业,或者 取消控制器发布 并防止对子级发布采取进一步操作。

  • 如果由于子项失败而导致控制器发布处于 HALTED 状态 并且忽略了子发布中失败的作业,即控制器 发布还原为 IN_PROGRESS 状态。

执行已配置的 Canary

如需运行 Canary 部署,请执行以下操作:

  1. 注册已配置的交付流水线和目标。

    gcloud deploy apply --file=PIPELINE
    

    该提交流水线包含针对您所选运行时的自动或自定义 Canary 配置。

    此命令假定您的目标在同一文件中定义,或者已以其他方式注册。如果没有,请务必注册您的目标平台。

  2. 创建版本:

    gcloud deploy releases create RELEASE_NAME \
                                  --delivery-pipeline=PIPELINE_NAME \
                                  --region=REGION
    

    PIPELINE_NAME 标识的交付流水线包含本文档中所述的自动化或自定义 Canary 配置。

  3. 推进 Canary 版:

    gcloud CLI

    gcloud deploy rollouts advance ROLLOUT_NAME \
                                --release=RELEASE_NAME \
                                --delivery-pipeline=PIPELINE_NAME \
                                --region=REGION
    

    其中:

    ROLLOUT_NAME 是当前发布的名称 您将进入下一阶段。

    RELEASE_NAME 是 其他项目

    PIPELINE_NAME 是配送名称 用于管理此版本部署的流水线。

    REGION 是区域 版本,例如 us-central1。这是必填项。

    请参阅 Google Cloud SDK 参考文档,详细了解 gcloud deploy rollouts advance 命令

    Google Cloud 控制台

    1. 打开“交付流水线”页面

    2. 点击交付流水线列表中显示的流水线。

      “交付流水线详细信息”页面以图形方式显示了 交付流水线的进展情况

    3. 发布标签页的交付流水线详情下,点击相应发布的名称。

      系统会显示该发布的发布详情页面。

      Google Cloud 控制台中的发布详情

      请注意,在此示例中,发布有 canary-50 阶段和 stable 阶段。您的发布可能有多个阶段 阶段。

    4. 点击推进发布

      发布将推进到下一阶段。

已跳过的阶段

如果您部署了 Canary 版本,但应用尚未部署到该运行时,Cloud Deploy 会跳过 Canary 阶段并运行稳定阶段。如需了解出现这种情况的原因,请参阅首次跳过阶段

后续步骤