你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

为 Azure Kubernetes 舰队管理器群集资源放置定义推出策略

在群集资源放置(CRP)的生存期内,可能会对 CRP 进行更改,这可能会导致以下情况之一:

  • 所有选定的群集可能需要承担新的工作负载
  • 已放置在选取的群集上的工作负荷可能会更新或删除
  • 以前选取的一些群集现已取消选取,并且必须从此类群集中删除工作负荷
  • 已新选取了一些群集,必须将工作负荷添加到这些群集中。

大多数情景可能会导致服务中断,因为 Fleet Manager 调度更新资源时,成员群集上运行的工作负荷可能会暂时不可用。 未被选择的群集将失去所有已放置的资源,从而导致网络流量丢失。 如果选择了太多新群集,并且机群管理器会同时将资源置于这些群集上,群集可能会过载。 确切的中断模式可能因放置的资源而异。

为了最大程度地减少中断,Fleet Manager 的群集资源放置允许用户配置推出策略,类似于本机 Kubernetes 部署,以便尽可能顺利地在更改之间进行转换。

本文介绍可用于群集资源放置的推出策略选项。

注释

如果不熟悉 Fleet Manager 的群集资源放置(CRP),请在阅读本文之前阅读 资源放置的概念概述

没有显式策略的默认行为

群集资源放置不需要定义推出策略。 如果未指定其中一个参数,则默认行为是使用 RollingUpdate 策略,其中 maxSurge 为 25%,maxUnavailable 为 25%,unavailablePeriodSeconds 为 10 秒。

滚动更新策略

要实现显式滚动更新策略,可以按如下示例将 strategy 规范添加到 CRP 中。 可以定义控制舰队管理器资源放置中断程度的参数。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourcePlacement
metadata:
  name: crp-example
spec:
  resourceSelectors:
    - group: ""
      kind: Namespace
      name: test-namespace
      version: v1
  policy:
    placementType: PickN
    numberOfClusters: 2
    affinity:
      clusterAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          clusterSelectorTerms:
            - labelSelector:
                matchLabels:
                  fleet.azure.com/___location: westus
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 50%

可以使用以下参数配置滚动更新策略:

  • maxUnavailable: 如果资源尚未成功应用于群集,则认为该群集不可用,并确保在任何时间 至少有(N - maxUnavailable)个群集是可用的。 可以设置为绝对数或百分比。 默认值为 25%,不应使用零。 将此参数设置为较低的值会导致更改期间中断较少,但导致推出速度较慢。

  • maxSurge: 确保在任何时候,可用的群集数量最多为(N + )。 可以设置为绝对数或百分比。 默认值为 25%,不应使用零。 将此参数设置为较低值会导致 Fleet Manager 在更多群集上放置较少的资源,从而减缓推出过程的速度。

  • unavailablePeriodSeconds 允许在资源评估为“就绪”之前定义一个时间段。 默认值为 60 秒。 在资源成功应用到该群集后,舰队管理器仅将群集上的新应用的资源视为“就绪” unavailablePeriodSeconds 秒。 将此参数设置为较低的值会导致更快的部署。 但是,强烈建议用户设置一个允许完成初始化/准备任务的值。

如何确定群集计数

机群管理器使用布置类型来确定在计算NmaxUnavailable时要使用的群集maxSurge的基线数:

  • PickFixedclusterNames的指定数目
  • PickAll:选取的群集数
  • PickNnumberOfClusters 值。

如果对参数使用百分比,则也会根据 N 该参数进行计算。

分阶段更新策略(预览版)

此推出策略在外部根据资源放置来定义,这种资源放置使用由使用 ClusterStagedUpdateStrategy 的舰队管理器应用的 ClusterStagedUpdateRun 自定义资源。

重要

Azure Kubernetes 舰队管理器预览功能可以通过自助服务方式选择性启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 客户支持部门会尽力为 Azure Kubernetes 舰队管理器预览功能提供部分支持。 因此,这些功能并不适合用于生产。

定义分阶段更新策略

您可以通过定义用于将群集分组到不同阶段的选择器来构建可重用策略,以确定群集获取位置的顺序。 在阶段内,可以控制群集排序,并且可以指定可选的放置后浸泡时间和审批。 可以命名并排序阶段以符合你的需求。

下图显示了一个示例更新策略,其中每个阶段包含三个阶段和多个群集。 阶段中是否包含群集取决于群集上的 environment 标签。 群集上的标签决定了 Canary 和生产阶段中的群集排序。 暂存和 Canary 之间存在一个小时的等待时间,需要批准才能从 Canary 转移到生产环境。

包含三个阶段(暂存、Canary 和生产)的放置暂存更新策略。每个阶段都包含多个群集,Canary 和生产阶段根据标签对群集应用排序。暂存和 Canary 之间需要等待 1 小时,需要批准才能从 Canary 过渡到生产阶段。

可以使用以下 ClusterStagedUpdateStrategy 定义来表示图表中的阶段性更新策略。

apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterStagedUpdateStrategy
metadata:
  name: example-staged-strategy
spec:
  stages:
    - name: staging
      labelSelector:
        matchLabels:
          environment: staging
      afterStageTasks:
        - type: TimedWait
          waitTime: 1h
    - name: canary
      labelSelector:
        matchLabels:
          environment: canary
      sortingLabelKey: name
      afterStageTasks:
        - type: Approval
    - name: production
      labelSelector:
        matchLabels:
          environment: production
      sortingLabelKey: order

使用分阶段更新策略

  1. 配置群集资源放置以使用类型为 External 的策略,如下所示。 将 CRP 提交到舰队中心群集时,不会进行放置。

    apiVersion: placement.kubernetes-fleet.io/v1beta1
    kind: ClusterResourcePlacement
    metadata:
      name: crp-staged-update-sample
    spec:
      resourceSelectors:
        - group: ""
          kind: Namespace
          name: test-namespace
          version: v1
      policy:
        placementType: PickAll
      strategy:
        type: External
    
  2. 创建一个 ClusterStagedUpdateStrategy (如前面所示),并针对 Fleet Manager 中心群集应用。

  3. 接下来,创建一个 ClusterStagedUpdateRun,确保引用要使用的 CRP 和策略。 还需要提供 ClusterResourceSnapshot 引用。 了解如何选择快照,可以通过阅读有关放置快照的文档。

    apiVersion: placement.kubernetes-fleet.io/v1beta1
    kind: ClusterStagedUpdateRun
    metadata:
      name: example-staged-update-run
    spec:
      placementName: crp-staged-update-sample
      resourceSnapshotIndex: "0"
      stagedRolloutStrategyName: example-staged-strategy
    
  4. 使用 kubectlClusterStagedUpdateRun 应用于 Fleet Manager 中心群集。

检查分阶段推出的状态

使用以下步骤确定分阶段推出的状态(包括 TimedWait 剩余的时间),或者是否有任何待处理的审批。

kubectl get clusterStagedUpdateRun example-staged-update-run

我们可以看到分阶段推出已初始化,并且已运行 44 秒。

NAME                        PLACEMENT                  RESOURCE-SNAPSHOT-INDEX   POLICY-SNAPSHOT-INDEX   INITIALIZED   SUCCEEDED   AGE
example-staged-update-run   crp-staged-update-sample   0                         0                       True                      13s

使用以下命令确定详细状态。

kubectl get clusterStagedUpdateRun example-staged-update-run -o yaml

此命令会生成一个详细响应,该响应提供有关推出位置的上下文。 以下示例已标注以便说明。

apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterStagedUpdateRun
metadata:
  ...
  name: example-staged-update-run
  ...
spec:
  placementName: crp-staged-update-sample
  resourceSnapshotIndex: "0"
  stagedRolloutStrategyName: example-staged-strategy
status:
  conditions:
  - lastTransitionTime: ...
    message: ClusterStagedUpdateRun initialized successfully
    observedGeneration: 1
    reason: UpdateRunInitializedSuccessfully
    status: "True"           # the updateRun is initialized successfully
    type: Initialized
  - lastTransitionTime: ...
    message: The update run is making progress
    observedGeneration: 1
    reason: UpdateRunProgressing
    status: "True"
    type: Progressing        # the updateRun is still running
  deletionStageStatus:
    clusters: []             # no clusters need to be cleaned up
    stageName: kubernetes-fleet.io/deleteStage
  policyObservedClusterCount: 3     # number of clusters to be updated 
  policySnapshotIndexUsed: "0"
  stagedUpdateStrategySnapshot:     # snapshot of the strategy
    stages:
    - afterStageTasks:
      - type: TimedWait
        waitTime: 1h0m0s
      labelSelector:
        matchLabels:
          environment: staging
      name: staging
    - afterStageTasks:
      - type: Approval
      labelSelector:
        matchLabels:
          environment: canary
      name: canary
      sortingLabelKey: name
    - labelSelector:
        matchLabels:
          environment: production
      name: production
      sortingLabelKey: order
  stagesStatus:                # detailed status for each stage
  - afterStageTaskStatus:
    - conditions:
      - lastTransitionTime: ...
        message: Wait time elapsed
        observedGeneration: 1
        reason: AfterStageTaskWaitTimeElapsed
        status: "True"         # the wait after-stage task has completed
        type: WaitTimeElapsed
      type: TimedWait
    clusters:
    - clusterName: member-cluster-02    # stage staging contains member-cluster-02 cluster only
      conditions:
      - lastTransitionTime: ...
        message: Cluster update started
        observedGeneration: 1
        reason: ClusterUpdatingStarted
        status: "True"
        type: Started
      - lastTransitionTime: ...
        message: Cluster update completed successfully
        observedGeneration: 1
        reason: ClusterUpdatingSucceeded
        status: "True"                  # member-cluster-02 is updated successfully
        type: Succeeded
    conditions:
    - lastTransitionTime: ...
      message: All clusters in the stage are updated and after-stage tasks are completed
      observedGeneration: 1
      reason: StageUpdatingSucceeded
      status: "False"
      type: Progressing
    - lastTransitionTime: ...
      message: Stage update completed successfully
      observedGeneration: 1
      reason: StageUpdatingSucceeded
      status: "True"                    # stage staging has completed successfully
      type: Succeeded
    endTime: ...
    stageName: staging
    startTime: ...
  - afterStageTaskStatus:
    - approvalRequestName: example-staged-update-run-canary # ClusterApprovalRequest name for this stage
      type: Approval
    clusters:
    - clusterName: member-cluster-01         # according the labelSelector and sortingLabelKey, member-cluster-01 is selected first in this stage
      conditions:
      - lastTransitionTime: ...
        message: Cluster update started
        observedGeneration: 1
        reason: ClusterUpdatingStarted
        status: "True"
        type: Started
      - lastTransitionTime: ...
        message: Cluster update completed successfully
        observedGeneration: 1
        reason: ClusterUpdatingSucceeded
        status: "True"                      # member-cluster-01 update is completed
        type: Succeeded
    - clusterName: member-cluster-03        # member-cluster-03 is selected after member-cluster-01 because of name label
      conditions:
      - lastTransitionTime: ...
        message: Cluster update started
        observedGeneration: 1
        reason: ClusterUpdatingStarted
        status: "True"                      # member-cluster-01 update has not finished yet
        type: Started
    conditions:
    - lastTransitionTime: ...
      message: Clusters in the stage started updating
      observedGeneration: 1
      reason: StageUpdatingStarted
      status: "True"                        # stage canary is still executing
      type: Progressing
    stageName: canary
    startTime: ...
  ...

提交对分阶段更新的审批

当分阶段更新策略包含审批时,需要使用以下方法来提交审批响应以继续分阶段推出。

审批数据负载是采用以下格式的 JSON 对象。

{
    "status":
    {
        "conditions":[
            {
                "type":"Approved",
                "status":"True",
                "reason":"reason for approval",
                "message":"longer message describing approval",
                "lastTransitionTime":"2025-03-12T06:15:21Z",
                "observedGeneration":1
            }
          ]
    }
}
  1. 检查待处理审批。

    kubectl get clusterapprovalrequest
    

    此命令会返回一个表,其中显示 UPDATE-RUN 中分阶段更新运行的名称,以及 STAGE 中需要审批的阶段。 阶段名称会被追加到更新运行的名称中,以形成ClusterApprovalRequest的名称。

    NAME                                 UPDATE-RUN                      STAGE    APPROVED   APPROVALACCEPTED   AGE
    example-staged-update-run-canary     example-staged-update-run       canary                                 2m2s
    
  2. 提交要批准的修补程序请求。

    kubectl patch clusterapprovalrequests example-staged-update-run-canary --type=merge -p '{"status":{"conditions":[{"type":"Approved","status":"True","reason":"testPassed","message":"lgtm","lastTransitionTime":"'$(date --utc +%Y-%m-%dT%H:%M:%SZ)'","observedGeneration":1}]}}' --subresource=status
    

    一个成功的提交,包含已应用修补程序的建议。

    clusterapprovalrequest.placement.kubernetes-fleet.io/example-staged-update-run-canary patched
    
  3. 还可以通过重新提交原始 clusterapprovalrequest文件来确认审批是否成功。

    kubectl get clusterapprovalrequest
    

    您可以在APPROVED列中查看已批准的状态,并在APPROVALACCEPTED列中看到它已被接受。

    NAME                                 UPDATE-RUN                      STAGE    APPROVED   APPROVALACCEPTED   AGE
    example-staged-update-run-canary     example-staged-update-run       canary   True       True               1m10s
    

后续步骤