使用 Gateway API 网络将 Canary 部署到 GKE 和 GKE Enterprise

本文档介绍了如何配置和使用 Canary 部署,以使用 Cloud Deploy 和 Kubernetes Gateway API 服务网格将应用部署到 GKE 或 GKE Enterprise。

Canary 部署是指逐步发布应用的新版本,即在监控应用性能的同时,逐渐增加发送到新版本的流量百分比。这有助于您及早发现潜在问题,并尽可能减少对用户的影响。

使用 Gateway API 时,GKE 和 GKE Enterprise 的 Canary 部署如何运作

  1. 除了 Deployment 和 Service 引用之外,您还提供了一个 HTTPRoute 资源,其中包含引用 Service 的 backendRefs 规则。

  2. Cloud Deploy 会创建一个新 Deployment,其名称为原始 Deployment 的名称加上 -canary;还会创建一个新 Service,其名称为原始 Service 的名称加上 -canary

    Secret、ConfigMap 和 Pod 横向自动扩缩器也会被复制并使用 -canary 重命名。

  3. 在每个 Canary 版阶段,Cloud Deploy 都会修改 HTTPRoute,以根据相应阶段的百分比更新原始 Deployment 的 pod 与 Canary 版 Deployment 的 pod 之间的权重。

    由于将更改传播到 HTTPRoute 资源可能会有延迟,因此您可以在配置中添加 routeUpdateWaitTime 属性,以便系统等待指定的时间来完成此传播。

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

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

    stable 阶段之前,Cloud Deploy 不会修改原始 Deployment 或 Service。

使用 Cloud Deploy,您可以在单个阶段或多个阶段中为 GKE 和 GKE Enterprise 配置 Canary 部署。

此处的说明仅包含特定于 Canary 版配置的内容。部署到 Google Kubernetes Engine 集群文档包含有关配置和执行部署流水线的一般说明。

确保您拥有所需的权限

除了使用 Cloud Deploy 所需的其他 Identity and Access Management 权限之外,您还需要以下权限才能执行可能需要用于灰度发布的其他操作:

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

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

准备好您的 skaffold.yaml

skaffold.yaml 文件定义了 Kubernetes 清单的呈现和部署方式。对于向 GKE/GKE Enterprise 进行的 Canary 部署,请确保它正确指向您的清单,并定义任何必要的 build 制品。除了标准部署所需的配置之外,skaffold.yaml 本身不需要任何特殊的 Canary 版专用配置。您可以使用 Skaffold 配置文件来管理自定义 Canary 阶段的不同清单变体。

准备 Kubernetes 清单

您的 Kubernetes 清单必须同时包含 Deployment 资源和 Service 资源。Service 必须定义一个与 Deployment 管理的 pod 的标签匹配的 selector。 Cloud Deploy 默认查找的标签是 app,但可以在流水线中配置此标签。

除了 DeploymentService 之外,您的清单还必须包含一个配置为流量拆分的 HTTPRoute 资源,该资源引用了 Service 和关联的网关。

配置自动化 Canary

使用 Kubernetes Gateway API(搭配 Istio 或任何受支持的实现)实现精确的百分比流量拆分,由网格/网关管理,由 Cloud Deploy 编排。

  1. 设置 Gateway API 资源:确保您的网关和底层服务网格(例如Istio)或网关控制器是否已在您的集群中正确配置。

  2. 在您创建发布版本时提供给 Cloud Deploy 的 Kubernetes 清单中,添加以下内容:

    • 引用网关资源的 HTTPRoute

    • 部署

    • 服务

  3. 配置交付流水线和要进行 Canary 部署的目标:

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

    • 特定目标的交付流水线配置(按进度顺序)包含一个 gatewayServiceMesh stanza,用于引用您的 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 是您的服务配置,Cloud Deploy 需要此配置才能将 Canary 版部署到 GKE 和 GKE Enterprise。

      • DEPLOYMENT 是您的 Deployment 配置,Cloud Deploy 需要此配置才能将 Canary 部署到 GKE 和 GKE Enterprise。

      • WAIT_TIME 是 Cloud Deploy 等待 HTTPRoute 资源更改完成传播的时间量,以避免请求被丢弃。例如:routeUpdateWaitTime: 60s

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

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

配置自定义 Canary

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

  • 发布阶段名称

    在全自动 Canary 版本中,Cloud Deploy 会为您命名阶段(例如 canary-25canary-75stable)。不过,借助自定义 Canary,您可以为每个阶段指定任意名称,只要该名称在相应 Canary 阶段的所有阶段中是唯一的,并且符合资源 ID 限制即可。但最终 (100%) 阶段名称必须为 stable

  • 各阶段的目标百分比

    分别指定每个阶段的百分比。

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

    您可以为每个阶段使用单独的 Skaffold 配置文件,也可以使用同一配置文件,或者使用任意组合。每个配置都可以使用不同的 Kubernetes 清单。 您还可以为给定阶段使用多个配置文件。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 stanza 中配置的顺序一致,但如果百分比值不是升序,则用于注册交付流水线的命令会因错误而失败。

请注意,Gateway API 自定义 Canary 版的配置不包含 runtimeConfig stanza。如果您添加了 runtimeConfig,则视为基于自定义服务的 Canary

配置自定义自动化 Canary

此功能将自定义阶段定义(名称、百分比、配置文件、验证、钩子)与 Cloud Deploy 的 GKE 或 GKE Enterprise 自动流量管理功能相结合。您定义阶段,但 Cloud Deploy 会根据百分比和所选的 runtimeConfig 处理底层资源操作。

如需进行配置,请在 strategy.canary 块中同时包含带有 serviceNetworkingruntimeConfig 部分和 customCanaryDeployment 部分(用于定义 phaseConfigs)。Cloud Deploy 将使用指定的 Skaffold 配置文件进行渲染,但会根据 runtimeConfig 和阶段百分比自动调整流量。

serialPipeline:
  stages:
  - targetId: gke-prod
    profiles: []
    strategy:
      canary:
        # Include runtimeConfig for automatic traffic management
        runtimeConfig:
          kubernetes:
            gatewayServiceMesh:
              httpRoute: "my-route"
              service: "my-app"
              deployment: "my-deployment"  
        # Include customCanaryDeployment for phase customization
        customCanaryDeployment:
          phaseConfigs:
          - phaseId: "warmup"
            percentage: 10
            profiles: ["profile-a"] # Profile used for rendering this phase
            verify: true
          - phaseId: "scaling"
            percentage: 50
            profiles: ["profile-b"] # Different profile for this phase
            verify: true
          - phaseId: "stable"
            percentage: 100
            profiles: ["profile-b"] # Can reuse profiles
            verify: true

将 HTTPRoute 部署到其他集群

如果您使用 Gateway API 服务网格配置了 Canary,则可以指定一个备用非目标集群来部署 HTTPRoute。

为此,您可以在 Canary 策略配置中使用 routeDestinations stanza 来标识 HTTPRoute 的目标集群,并使用布尔值设置将服务传播到同一非目标集群。您可以在目标配置中创建 associatedEntities stanza 来标识集群。

  1. 在目标上配置 associatedEntities

    每个实体都是一个集群,Cloud Deploy 会将 HTTPRoute 和(可选)Kubernetes 服务部署到该集群中。 在目标定义中,添加 associatedEntities 节:

    associatedEntities:
      [KEY]:
        gkeClusters:
        - cluster: [PATH]
          dnsEndpoint: [true|false]
          internalIp: [true|false]
          proxyUrl:
    

    其中:

    • KEY 是此关联实体组的任意名称。您将使用此名称在 Canary 配置中引用 routeDestinations 中的实体。

    • PATH 是标识 HTTPRoute(以及可选的服务)将部署到的 GKE 集群的资源路径。

    • dnsEndpoint 表示在配置了多个端点时是否使用集群的 DNS 端点。默认值为 false

    • internalIp 表示在配置了多个端点时是否使用集群的内部 IP(专用 IP)。默认值为 false

    您可以添加任意数量的集群,无论是否包含 internalIp

  2. 在 Canary 配置中配置 routeDestinations

    每个路由目的地都引用一个 associatedEntities stanza,并指明是否还要将服务部署到备用集群。在 Canary 配置的 gatewayServiceMesh stanza 中添加以下内容:

    routeDestinations:
      destinationIds: ["KEY"]
      propagateService: [true|false]
    

    其中:

    • KEY 是您在目标 associatedEntities 中配置的名称。使用此名称在 Canary 配置中引用 routeDestinations 中的实体。

      您还可以提供值 @self,以便将 HTTPRoute 部署到目标集群以及关联的目标位置。

    • propagateService 表示除了 HTTPRoute 之外,您是否还要将 Service 部署到关联的集群。默认值为 false

执行 GKE 或 GKE Enterprise Canary

  1. 注册流水线和目标:应用交付流水线和 GKE 或 GKE Enterprise 目标配置文件。

    
    gcloud deploy apply --file=delivery-pipeline.yaml --region=REGION
    gcloud deploy apply --file=gke-targets.yaml --region=REGION
    

    交付流水线包含所选运行时的自动化或自定义 Canary 配置。

  2. 创建版本:启动部署,并提供映像名称。

    
    gcloud deploy releases create RELEASE_NAME \
                                    --delivery-pipeline=PIPELINE_NAME \
                                    --region=REGION
      # e.g., --images=my-cloudrun-service=gcr.io/my-project/my-app:v1.1
      # Add --skaffold-file or --source if not using default Skaffold config discovery
    

    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。这是必填项。

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

    Google Cloud 控制台

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

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

      交付流水线详情页面显示交付流水线进展的图形表示。

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

      系统会显示相应发布版本的发布详情页面。

       Google Cloud 控制台中的发布作业详情

      请注意,在此示例中,发布包含 canary-50 阶段和 stable 阶段。您的分阶段发布可能包含更多阶段或不同的阶段。

    4. 点击推进发布

      发布作业推进到下一阶段。

已跳过的阶段

如果您部署的是 Canary 版本,但您的应用尚未部署到该运行时,Cloud Deploy 会跳过 Canary 阶段,直接运行稳定版阶段。如需了解发生此问题的原因,请参阅首次跳过阶段

后续步骤