本文档介绍了如何配置和使用 Canary 部署策略。
什么是 Canary 部署?
Canary 部署是一种应用的渐进式发布方式,它会在已部署的版本和新版本之间拆分流量,先面向部分用户发布,然后再全面发布。
支持的目标类型
Cloud Deploy 中的 Canary 部署支持所有目标类型,包括:
- Google Kubernetes Engine
- Cloud Run(仅限服务,不包括作业)。
- GKE Enterprise
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 中执行 Canary 部署的方式如下:
您需要提供部署资源和服务资源的名称。
Cloud Deploy 会创建一个额外的部署资源,其名称为当前部署的名称加上
-canary
。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
进行复制和重命名。在
stable
阶段,-canary
部署会缩减为零,原始部署会被新部署取代。在
stable
阶段之前,Cloud Deploy 不会修改原始部署。
Cloud Deploy 会预配 pod,以尽可能接近所请求的 Canary 版百分比。此值取决于 Pod 数量,而不是 Pod 的流量。如果您希望金丝雀版本根据流量进行分流,则需要使用 Gateway API。
对于基于 GKE 网络的 Canary 版,您可以启用或停用 Pod 过度配置。以下部分介绍了 Cloud Deploy 如何计算每个 Canary 阶段要为 Canary 部署预配的 pod 数量。
启用超额预配的 Pod 预配
启用过度配置 (disablePodOverprovisioning: false
) 后,Cloud Deploy 会根据运行现有部署的 pod 数量,创建足够多的额外 pod 来运行您所需的 Canary 版百分比。以下公式展示了启用 pod 过度配置时,Cloud Deploy 如何计算每个 Canary 阶段要为 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/Enterprise
Cloud Deploy 使用 Gateway API 在 GKE 和 GKE Enterprise 中执行 Canary 部署的方式如下:
除了部署和服务引用之外,您还需要提供一个 HTTPRoute 资源,其中包含引用服务的
backendRefs
规则。Cloud Deploy 会创建一个新的部署,其名称为原始部署名称加上
-canary
,并创建一个新的服务,其名称为原始服务名称加上-canary
。此外,系统还会复制并使用
-canary
重命名 Secret、ConfigMap 和横向 Pod 自动扩缩器。对于每个 Canary 阶段,Cloud Deploy 都会修改 HTTPRoute,以根据相应阶段的百分比更新原始部署的 pod 和 Canary 部署的 pod 之间的权重。
由于向
HTTPRoute
资源传播更改可能会出现延迟,因此您可以在配置中添加routeUpdateWaitTime
属性,以便系统等待指定的时间来进行此传播。在
stable
阶段,-canary
部署会缩减为零,原始部署会更新为使用新版本的部署。此外,HTTPRoute 现在已恢复为您提供的原始路由。
在
stable
阶段之前,Cloud Deploy 不会修改原始部署或服务。
Cloud Run
Cloud Deploy 会按如下方式为 Cloud Run 执行 Canary 部署:
对于要部署到 Cloud Run 的 Canary 版本,请勿在服务 YAML 中提供
traffic
诗节。为 Canary 版本创建新的发布版本时,Cloud Deploy 会在 Cloud Deploy 成功部署的先前修订版本和新修订版本之间拆分流量。
如果您想查看 Canary 部署各个阶段之间的差异,可以查看版本检查器中提供的每个阶段呈现的清单中的更改。您甚至可以在发布前执行此操作。此外,如果您使用的是并行部署,还可以检查每个子项的呈现清单。
配置 Canary 部署
本部分介绍了如何为 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 选择器标签。此标签必须与清单中定义的 Kubernetes 服务中的标签选择器相匹配。这项设置为可选设置。默认值为
app
。PERCENTAGES 是表示 Canary 增量百分比值的逗号分隔列表,例如
[5, 25, 50]
。此外,这不包括
100
,因为在 Canary 版中,系统假定已 100% 部署,并由stable
阶段处理。您可以启用部署验证 (
verify: true
)。如果您这样做,系统会在每个阶段启用verify
作业。PREDEPLOY_ACTION
与您在
skaffold.yaml
中用于定义要在部署前运行的自定义操作的 ACTION_NAME 相同。POSTDEPLOY_ACTION
与您在
skaffold.yaml
中用于定义要部署后运行的自定义操作的 ACTION_NAME 相同。
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
与您在
skaffold.yaml
中用于定义要部署后运行的自定义操作的 ACTION_NAME 相同。
配置自定义 Canary
您可以手动配置 Canary 版本,而不是完全依赖 Cloud Deploy 提供的自动化功能。使用自定义 Canary 配置时,您需要在交付流水线定义中指定以下内容:
发布阶段名称
在完全自动化的 Canary 版中,Cloud Deploy 会为您命名各个阶段(例如
canary-25
、canary-75
、stable
)。不过,对于自定义 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
与您在
skaffold.yaml
中用于定义要在部署前运行的自定义操作的 ACTION_NAME 相同。POSTDEPLOY_ACTION
与您在
skaffold.yaml
中用于定义要部署后运行的自定义操作的 ACTION_NAME 相同。
最后一个阶段的百分比必须为 100
。系统会按照您在此 customCanaryDeployment
诗节中配置的顺序执行相应阶段,但如果百分比值不是按升序排列,用于注册传送流水线的命令将会失败并返回错误。
请注意,自定义 Canary 的配置不包含 runtimeConfig
诗节。如果您添加了 runtimeConfig
,则系统会将其视为自定义自动化 Canary 版本。
配置自定义自动化 Canary
自定义自动化 Canary 与自定义 Canary 类似,因为您可以使用自定义阶段名称、百分比值、Skaffold 配置文件、验证作业以及预部署和发布后作业来指定单独的 Canary 阶段。不过,使用自定义 Canary 时,您无需提供用于定义流量分配的配置,Cloud Deploy 会为您完成此操作,但您仍然需要提供要用于每个阶段的 Skaffold 配置文件。
如需配置自定义自动化 Canary,请添加 runtimeConfig
诗节(如此处所示),并添加 customCanaryDeployment
诗节(如此处所示)。
使用 Kubernetes Gateway API 服务网格配置 Canary 部署
虽然您可以使用 Cloud Deploy 金丝雀部署来将应用部署到基于服务的 Kubernetes 网络,但另一种方法是使用 Kubernetes Gateway API 服务网格。本部分介绍了具体方法。
您可以将 Gateway API 与 Istio 或任何受支持的实现搭配使用。
设置 Gateway API 资源:
以上仅为示例。
在您创建版本时提供给 Cloud Deploy 的 Kubernetes 清单中,添加以下内容:
引用网关资源的
HTTPRoute
部署
服务
配置交付流水线以及要将 Canary 部署到其上的目标:
目标的配置与任何其他目标的配置相同。
在特定目标的进度序列中,提交流水线配置包含一个
gatewayServiceMesh
诗节,用于引用您的 Kubernetes Gateway APIHTTPRoute
配置以及您的部署和服务。strategy: canary: runtimeConfig: kubernetes: gatewayServiceMesh: httpRoute: "ROUTE" service: "SERVICE" deployment: "DEPLOYMENT" routeUpdateWaitTime: "WAIT_TIME" podSelectorLabel: "LABEL" canaryDeployment: percentages: - 50
其中...
ROUTE 是 httpRoute 配置,用于定义所需的路由行为。
SERVICE 是您的服务配置,Cloud Deploy 需要此配置才能将 Canary 版部署到 GKE 和 GKE Enterprise。
DEPLOYMENT 是您的部署配置,Cloud Deploy 需要此配置才能将 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 部署一样,如果您要部署到 GKE 目标,则需要在清单中添加 Kubernetes Deployment 配置和 Kubernetes Service 配置。
与单目标 Canary 部署一样,您的交付流水线配置必须在适用阶段的阶段定义中包含
strategy.canary
诗节。此外,您还需要配置多目标,并配置该多目标引用的子目标。
-
这两种类型的发布(控制组和子组)都针对所有配置的 Canary 百分比设置了单独的阶段,并针对 100% 的 Canary 设置了
stable
阶段。 您无法推进子发布。
您只能推进控制器发布。当您将控制器发布作业推进到下一阶段时,Cloud Deploy 也会推进子发布作业。
您无法在控制器部署中重试失败的作业。
您只能在子发布中重试作业。
您无法在控制器发布中忽略失败的作业。
您只能忽略子发布中的失败作业。
您可以取消控制器发布,但无法取消子发布。
您只能在子发布(而非控制器发布)下终止作业运行。
如果 Canary 版本中的并行发布失败,该怎么办
当子发布失败时,控制器发布可能会转换到不同的状态,具体取决于子发布的具体情况:
如果一项或多项子发布失败,但至少一项子发布仍处于
IN_PROGRESS
状态,则控制器发布仍处于IN_PROGRESS
状态。如果一项或多项子发布失败,但至少有一项子发布成功,并且当前阶段后面还有其他阶段,则控制器发布状态为
HALTED
。如果这是
stable
阶段,则控制器发布版本为FAILED
。如果控制器发布因子发布失败而处于
HALTED
状态,并且您忽略了子发布中的失败作业,则控制器发布会恢复为IN_PROGRESS
状态。
将 HTTPRoute 部署到其他集群
使用 Gateway API 服务网格配置 Canary 后,您可以指定一个非目标集群作为备用集群来部署 HTTPRoute。
为此,您可以在 Canary 策略配置中使用 routeDestinations
诗节来识别 HTTPRoute 的目标集群,并使用布尔值设置将服务传播到同一非目标集群。您还需要在目标配置中创建 associatedEntities
诗节来标识这些集群。
在目标设备上配置
associatedEntities
。每个实体都是一个集群,Cloud Deploy 将在其中部署 HTTPRoute 和(可选)Kubernetes 服务。在目标定义中,添加
associatedEntities
诗节:associatedEntities: [KEY]: gkeClusters: - cluster: [PATH] internalIp: [true|false] proxyUrl:
其中:
KEY
是这组关联实体的任意名称。您将使用此名称在 Canary 配置中引用routeDestinations
中的实体。PATH
是标识将部署 HTTPRoute(以及可选的 Service)的 GKE 集群的资源路径。如果集群同时配置了内部 IP 和公共 IP,
internalIp
用于指示您是否要使用内部 IP(专用 IP)。默认值为false
。
您可以添加任意数量的集群,无论是否包含
internalIp
。在 Canary 配置中配置
routeDestinations
。每条路由目的地都引用一个
associatedEntities
诗节,并指明是否还要将服务部署到备用集群。在 Canary 配置的gatewayServiceMesh
节中添加以下代码:routeDestinations: destinationIds: ["KEY"] propagateService: [true|false]
其中:
KEY
是您在目标associatedEntities
中配置的名称。您可以使用此名称在 Canary 配置中引用routeDestinations
中的实体。除了关联的目标之外,您还可以提供值
@self
将 HTTPRoute 部署到目标集群。propagateService
用于指明您是否希望将服务部署到关联的集群(除了 HTTPRoute 之外)。默认值为false
。
执行已配置的 Canary
如需运行 Canary 部署,请执行以下操作:
注册已配置的交付流水线和目标。
gcloud deploy apply --file=PIPELINE
该提交流水线包含针对您所选运行时的自动或自定义 Canary 配置。
此命令假定您的目标在同一文件中定义,或者已以其他方式注册。如果没有,请务必注册您的目标平台。
创建版本:
gcloud deploy releases create RELEASE_NAME \ --delivery-pipeline=PIPELINE_NAME \ --region=REGION
由
PIPELINE_NAME
标识的交付流水线包含本文档中所述的自动化或自定义 Canary 配置。推进 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
。这是必填项。如需详细了解
gcloud deploy rollouts advance
命令,请参阅 Google Cloud SDK 参考文档。Google Cloud 控制台
点击交付流水线列表中显示的流水线。
交付流水线详情页面显示交付流水线进展的图形表示。
在发布标签页的交付流水线详情下,点击相应发布的名称。
系统会显示相应发布的详情页面。
请注意,在此示例中,发布有
canary-50
阶段和stable
阶段。您的发布可能包含更多或不同的阶段。点击推进发布。
发布作业会推进到下一阶段。
已跳过的阶段
如果您部署了 Canary 版本,但应用尚未部署到该运行时,Cloud Deploy 会跳过 Canary 阶段并运行稳定阶段。如需了解出现这种情况的原因,请参阅首次跳过阶段。
后续步骤
了解如何管理 Canary 版本的生命周期。
详细了解并行部署。