将 Kubernetes 资源从中心群集放置到成员群集

本文介绍使用 Azure Kubernetes 舰队管理器(舰队)将 Kubernetes 资源从中心群集放置到成员群集的概念。

平台管理员通常需要将 Kubernetes 资源部署到多个群集,这出于多种原因,例如:

  • 使用跨多个群集的角色和角色绑定来管理访问控制。
  • 运行需要位于所有群集上的基础结构应用程序,例如 Prometheus 或 Flux。

应用程序开发人员通常需要将 Kubernetes 资源部署到多个群集,这出于各种原因,例如:

  • 将视频服务应用程序部署到不同区域的多个群集,以获得低延迟观看体验。
  • 将购物车应用程序部署到两个配对区域,以便客户能够在单个区域中断期间继续购物。
  • 将批处理计算应用程序部署到具有廉价现成节点池的群集。

跨多个群集手动创建、更新和跟踪这些 Kubernetes 资源非常繁琐。 舰队提供 Kubernetes 资源传播,以大规模管理 Kubernetes 资源。 使用 Kubernetes 舰队,你可以在中心群集中创建 Kubernetes 资源,并通过 Kubernetes 客户资源将其传播到所选成员群集:MemberClusterClusterResourcePlacement

Kubernetes Fleet 支持基于开源云原生解决方案的这些自定义资源,可以在开源舰队文档中详细了解这些资源。

介绍 ClusterResourcePlacement

ClusterResourcePlacement 对象用于告知舰队日程安排如何将给定的群集范围对象从舰队中心群集放置到成员群集中。 选择命名空间范围的对象(如 Deployment、StatefulSets、DaemonSets、ConfigMaps、Secrets 和 PersistentVolumeClaims)包含的命名空间时,包含这些对象。

通过 ClusterResourcePlacement,您可以:

  • 选择要传播到成员群集的群集范围的 Kubernetes 资源。
  • 指定放置策略,以便手动或自动选择成员群集作为目标群集。
  • 指定推出策略,以便安全地将所选 Kubernetes 资源的任何更新推出到多个目标群集。
  • 查看向每个目标群集的传播进度。

下图显示了一个示例。

显示 Kubernetes 资源如何传播到成员群集的示意图。

封装处理资源

ClusterResourcePlacement 支持使用 ConfigMap 来封装某些 Kubernetes 资源类型,以便在中心群集上暂存这些资源类型,而不会对中心群集产生任何意外的副作用。 有关资源类型的列表及了解此功能的工作原理,请参阅封装对象文档

放置类型

以下放置类型可用于控制指定的 Kubernetes 资源需要传播到的群集数量:

  • PickFixed 按名称将资源放入成员群集的特定列表中。
  • PickAll 将资源置于所有成员群集或满足条件的所有成员群集上。 此策略可用于放置基础结构工作负荷,例如群集监视或报告应用程序。
  • PickN 是最灵活的放置选项,允许根据相关性或拓扑分布约束选择群集,并且在将工作负荷分散到多个适当的群集以确保可用性时非常有用。

PickFixed 放置类型

若要将工作负载部署到一组已知的成员群集中,可以使用 PickFixed 放置策略按名称选择群集。

clusterNames 是此放置类型唯一有效的策略选项。

以下示例显示如何将 test-deployment 命名空间部署到成员群集 cluster1cluster2 中。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourcePlacement
metadata:
  name: crp-fixed
spec:
  policy:
    placementType: PickFixed
    clusterNames:
    - cluster1
    - cluster2
  resourceSelectors:
    - group: ""
      kind: Namespace
      name: test-deployment
      version: v1

PickAll 放置类型

可以使用 PickAll 放置类型在舰队中的所有成员群集上部署工作负载,或部署到符合所设置条件的群集子集。

创建此类型的放置时,可以指定以下群集相关性类型:

  • requiredDuringSchedulingIgnoredDuringExecution:由于这种策略是计划期间所需的,因此会根据指定条件对群集进行筛选。

以下示例展示了如何在标有 environment: production 的所有群集中部署 prod-deployment 命名空间及其所有对象:

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourcePlacement
metadata:
  name: crp-pickall
spec:
  policy:
    placementType: PickAll
    affinity:
        clusterAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
                clusterSelectorTerms:
                - labelSelector:
                    matchLabels:
                        environment: production
  resourceSelectors:
    - group: ""
      kind: Namespace
      name: prod-deployment
      version: v1

PickN 放置类型

PickN 放置类型是最灵活的选项,允许根据相关性和拓扑分布约束将资源放置在可配置数量的群集中。

创建此类型的放置时,可以指定以下群集相关性类型:

  • requiredDuringSchedulingIgnoredDuringExecution:由于这种策略是计划期间所需的,因此会根据指定条件对群集进行筛选。
  • preferredDuringSchedulingIgnoredDuringExecution:由于这种策略是计划期间首选策略,但不是所需的,因此会根据指定条件对群集进行排列。

可以同时设置必需和首选相关性。 所需的关联可防止放置到不匹配的群集,并且首选相关性提供有效群集的排序。

具有相关性的 PickN

将相关性与 PickN 放置策略函数一起使用与将相关性与 Pod 日程安排一起使用类似。

以下示例展示了如何将工作负载部署到三个群集中。 只有具有 critical-allowed: "true" 标签的群集是有效的放置目标,优先选择具有标签 critical-level: 1 的群集:

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourcePlacement
metadata:
  name: crp-pickn-01
spec:
  resourceSelectors:
    - ...
  policy:
    placementType: PickN
    numberOfClusters: 3
    affinity:
        clusterAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
              weight: 20
              preference:
              - labelSelector:
                  matchLabels:
                    critical-level: 1
            requiredDuringSchedulingIgnoredDuringExecution:
                clusterSelectorTerms:
                - labelSelector:
                    matchLabels:
                      critical-allowed: "true"

具有拓扑分布约束的 PickN

可以使用拓扑分布约束来强制跨拓扑边界划分群集放置,以满足可用性要求。 例如,使用这些约束跨区域或更新通道拆分位置。 还可以配置拓扑分布约束,以在无法满足约束时阻止安排 (whenUnsatisfiable: DoNotSchedule) 或尽可能进行安排 (whenUnsatisfiable: ScheduleAnyway)。

以下示例演示如何将给定的资源集分散到多个区域,并尝试在不同的更新日跨成员群集进行日程安排。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourcePlacement
metadata:
  name: crp-pickn-02
spec:
  resourceSelectors:
    - ...
  policy:
    placementType: PickN
    topologySpreadConstraints:
    - maxSkew: 2
      topologyKey: region
      whenUnsatisfiable: DoNotSchedule
    - maxSkew: 2
      topologyKey: updateDay
      whenUnsatisfiable: ScheduleAnyway

有关详细信息,请参阅开源舰队文档拓扑分布约束

放置策略选项

下表汇总了每种放置类型的可用计划策略字段。

“策略”字段 PickFixed PickAll PickN
placementType
affinity
clusterNames
numberOfClusters
topologySpreadConstraints

基于标签和属性选择群集

用于选择群集的可用标签和属性

使用 PickNPickAll 放置类型时,可以将以下标签和属性用作策略的一部分。

标签

以下标签会自动添加到所有成员群集,并可以用于资源放置策略中的目标群集选择。

Label 说明
fleet.azure.com/location 群集的 Azure 区域 (westus)
fleet.azure.com/resource-group 群集的 Azure 资源组 (rg_prodapps_01)
fleet.azure.com/subscription-id 群集所在的 Azure 订阅标识符。 格式为 UUID/GUID。

还可以使用应用于群集的任何自定义标签。

属性

以下属性可用作放置策略的一部分。

CPU 和内存属性表示为 Kubernetes 资源单元

成本属性是十进制数,表示用于群集中节点的 Azure 计算的每小时成本(以美元为单位)。 成本基于 Azure 公共定价。

属性名称 说明
kubernetes-fleet.io/node-count 成员群集上的可用节点。
resources.kubernetes-fleet.io/total-cpu 群集的 CPU 资源单位总数。
resources.kubernetes-fleet.io/allocatable-cpu 群集的可分配 CPU 资源单元。
resources.kubernetes-fleet.io/available-cpu 群集的可用 CPU 资源单元。
resources.kubernetes-fleet.io/total-memory 群集的内存资源单元总数。
resources.kubernetes-fleet.io/allocatable-memory 群集的可分配内存资源单元。
resources.kubernetes-fleet.io/available-memory 群集的可用内存资源单元。
kubernetes.azure.com/per-cpu-core-cost 群集的每个 CPU 核心成本。
kubernetes.azure.com/per-gb-memory-cost 群集的每 GiB 内存成本。

指定选择匹配条件

在策略条件中使用群集属性时,可以指定:

  • 名称:属性的名称,这是本文的属性中列出的属性之一。

  • 运算符:运算符用于表示约束/所需值与群集上观察到的值之间的条件。 当前支持以下运算符:

    • Gt(大于):群集给定属性观察到的值必须大于条件中的值,然后才能选取资源放置。
    • Ge(大于或等于):群集给定属性观察到的值必须大于或等于条件中的值,然后才能选取资源放置。
    • Lt(小于):群集给定属性观察到的值必须小于条件中的值,然后才能选取资源放置。
    • Le(小于或等于):群集给定属性观察到的值必须小于或等于条件中的值,然后才能选取资源放置。
    • Eq(等于):群集给定属性观察到的值必须等于条件中的值,然后才能选取资源放置。
    • Ne(不等于):群集给定属性观察到的值必须不等于条件中的值,然后才能选取资源放置。

    如果使用运算符 GtGeLtLeEqNe,则条件中的值列表应正好有一个值。

  • 值:值列表,这些值是属性的可能值。

舰队根据条件中指定的属性评估每个群集。 未能满足 requiredDuringSchedulingIgnoredDuringExecution 下列出的条件会从资源放置中排除此成员群集。

注意

如果成员群集不具有条件中表示的属性,则将自动使条件失败。

下面是一个示例放置策略,用于选择包含仅五个或更多节点的群集。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourcePlacement
metadata:
  name: crp
spec:
  resourceSelectors:
    - ...
  policy:
    placementType: PickAll
    affinity:
        clusterAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
                clusterSelectorTerms:
                - propertySelector:
                    matchExpressions:
                    - name: "kubernetes-fleet.io/node-count"
                      operator: Ge
                      values:
                      - "5"

属性排名的工作原理

使用 preferredDuringSchedulingIgnoredDuringExecution 时,属性排序器会根据其值按升序或降序顺序设置舰队中所有群集的优先级。 用于排序的权重是根据指定的值计算的。

属性排序器包括:

  • 名称:群集属性的名称。
  • 排序顺序:排序顺序可以是 Ascending,也可以是 Descending。 使用 Ascending 顺序时,首选具有较低观察到的值的成员群集。 使用 Descending 顺序时,首选具有较高观察到的值的成员群集。
降序

对于排序顺序降序,使用公式计算成比例权重:

((Observed Value - Minimum observed value) / (Maximum observed value - Minimum observed value)) * Weight

例如,假设要根据可用 CPU 容量的属性按降序顺序设置群集的优先级,并且有一个包含三个群集的舰队,其中包含以下可用 CPU:

群集 可用 CPU 容量
cluster-a 100
cluster-b 20
cluster-c 10

在这种情况下,排序器将计算以下权重:

群集 可用 CPU 容量 计算 Weight
cluster-a 100 (100 - 10) / (100 - 10) 100%
cluster-b 20 (20 - 10) / (100 - 10) 11.11%
cluster-c 10 (10 - 10) / (100 - 10) 0%
升序

对于排序顺序升序,使用公式计算成比例权重:

(1 - ((Observed Value - Minimum observed value) / (Maximum observed value - Minimum observed value))) * Weight

例如,假设要根据可用 CPU 核心成本按升序顺序设置群集的优先级,并且有一个包含三个群集的舰队,其中包含以下 CPU 核心成本:

群集 每 CPU 核心成本
cluster-a 1
cluster-b 0.2
cluster-c 0.1

在这种情况下,排序器将计算以下权重:

群集 每 CPU 核心成本 计算 Weight
cluster-a 1 1 - ((1 - 0.1) / (1 - 0.1)) 0%
cluster-b 0.2 1 - ((0.2 - 0.1) / (1 - 0.1)) 88.89%
cluster-c 0.1 1 - (0.1 - 0.1) / (1 - 0.1) 100%

使用容忍

ClusterResourcePlacement 对象支持适用于 ClusterResourcePlacement 对象的容忍规范。 每个容忍对象包含以下字段:

  • key:容忍的键。
  • value:容忍的值。
  • effect:容忍的影响,如 NoSchedule
  • operator:容忍的运算符,如 ExistsEqual

每个容忍用于容忍应用于 ClusterResourcePlacement 的一个或多个特定的污点。 容忍对 MemberCluster 的所有污点后,计划程序便可将资源传播到群集。 创建 ClusterResourcePlacement 对象后,就不能更新或删除其中的容忍。

有关详细信息,请参阅有关容忍的开源舰队文档

配置推出策略

舰队使用滚动更新策略来控制如何在群集之间推出更新。

在以下示例中,舰队计划程序按顺序将更新推出到每个群集,在群集之间至少等待 unavailablePeriodSeconds。 如果所有资源都已正确应用于群集,则推出状态被视为成功。 推出状态检查不会级联到子资源,因此举个例子,它不会确认部署创建的 Pod 是否已准备就绪。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourcePlacement
metadata:
  name: crp
spec:
  resourceSelectors:
    - ...
  policy:
    ...
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
      unavailablePeriodSeconds: 60

有关详细信息,请参阅有关推出策略的开源舰队文档

确定放置状态

舰队计划程序将有关放置决策的详细信息和状态更新到 ClusterResourcePlacement 对象。 输出包括以下信息:

  • 当前适用于放置的条件,包括是否已成功完成放置。
  • 每个成员群集的放置状态部分,其中显示了部署到该群集的状态。

以下示例显示了一个 ClusterResourcePlacement,它使用 PickNtest 命名空间及 test-1 ConfigMap 部署到两个成员群集中。 放置已成功完成,资源已放入 aks-member-1aks-member-2 群集中。

可以使用 kubectl describe crp <name> 命令查看此信息。

kubectl describe crp crp-1
Name:         crp-1
Namespace:
Labels:       <none>
Annotations:  <none>
API Version:  placement.kubernetes-fleet.io/v1
Kind:         ClusterResourcePlacement
Metadata:
  ...
Spec:
  Policy:
    Number Of Clusters:  2
    Placement Type:      PickN
  Resource Selectors:
    Group:
    Kind:                  Namespace
    Name:                  test
    Version:               v1
  Revision History Limit:  10
Status:
  Conditions:
    Last Transition Time:  2023-11-10T08:14:52Z
    Message:               found all the clusters needed as specified by the scheduling policy
    Observed Generation:   5
    Reason:                SchedulingPolicyFulfilled
    Status:                True
    Type:                  ClusterResourcePlacementScheduled
    Last Transition Time:  2023-11-10T08:23:43Z
    Message:               All 2 cluster(s) are synchronized to the latest resources on the hub cluster
    Observed Generation:   5
    Reason:                SynchronizeSucceeded
    Status:                True
    Type:                  ClusterResourcePlacementSynchronized
    Last Transition Time:  2023-11-10T08:23:43Z
    Message:               Successfully applied resources to 2 member clusters
    Observed Generation:   5
    Reason:                ApplySucceeded
    Status:                True
    Type:                  ClusterResourcePlacementApplied
  Placement Statuses:
    Cluster Name:  aks-member-1
    Conditions:
      Last Transition Time:  2023-11-10T08:14:52Z
      Message:               Successfully scheduled resources for placement in aks-member-1 (affinity score: 0, topology spread score: 0): picked by scheduling policy
      Observed Generation:   5
      Reason:                ScheduleSucceeded
      Status:                True
      Type:                  ResourceScheduled
      Last Transition Time:  2023-11-10T08:23:43Z
      Message:               Successfully Synchronized work(s) for placement
      Observed Generation:   5
      Reason:                WorkSynchronizeSucceeded
      Status:                True
      Type:                  WorkSynchronized
      Last Transition Time:  2023-11-10T08:23:43Z
      Message:               Successfully applied resources
      Observed Generation:   5
      Reason:                ApplySucceeded
      Status:                True
      Type:                  ResourceApplied
    Cluster Name:            aks-member-2
    Conditions:
      Last Transition Time:  2023-11-10T08:14:52Z
      Message:               Successfully scheduled resources for placement in aks-member-2 (affinity score: 0, topology spread score: 0): picked by scheduling policy
      Observed Generation:   5
      Reason:                ScheduleSucceeded
      Status:                True
      Type:                  ResourceScheduled
      Last Transition Time:  2023-11-10T08:23:43Z
      Message:               Successfully Synchronized work(s) for placement
      Observed Generation:   5
      Reason:                WorkSynchronizeSucceeded
      Status:                True
      Type:                  WorkSynchronized
      Last Transition Time:  2023-11-10T08:23:43Z
      Message:               Successfully applied resources
      Observed Generation:   5
      Reason:                ApplySucceeded
      Status:                True
      Type:                  ResourceApplied
  Selected Resources:
    Kind:       Namespace
    Name:       test
    Version:    v1
    Kind:       ConfigMap
    Name:       test-1
    Namespace:  test
    Version:    v1
Events:
  Type    Reason                     Age                    From                                   Message
  ----    ------                     ----                   ----                                   -------
  Normal  PlacementScheduleSuccess   12m (x5 over 3d22h)    cluster-resource-placement-controller  Successfully scheduled the placement
  Normal  PlacementSyncSuccess       3m28s (x7 over 3d22h)  cluster-resource-placement-controller  Successfully synchronized the placement
  Normal  PlacementRolloutCompleted  3m28s (x7 over 3d22h)  cluster-resource-placement-controller  Resources have been applied to the selected clusters

放置更改触发器

舰队计划程序优先考虑现有工作负荷放置的稳定性。 此优先性可以限制导致工作负荷被删除和重新安排的更改数量。 以下场景可能会触发放置更改:

  • ClusterResourcePlacement 对象中的放置策略更改可能会触发工作负荷的删除和重新安排。
    • 横向扩展操作(增加 numberOfClusters 且无其他更改)只会在新群集上放置工作负载,不会影响现有放置。
  • 群集更改,包括:
    • 如果新群集满足放置策略(例如 PickAll 策略),则符合条件的新群集可能会触发放置。
    • 放置位置的群集将从舰队中删除。 根据策略不同,计划程序会尝试将所有受影响的工作负载放置在剩余群集上,而不会影响现有放置。

仅资源更改(更新 ClusterResourcePlacement 对象中的资源或更新 ResourceSelector)会在现有放置中逐步推出,但不触发工作负荷重新安排。

后续步骤