分发策略
Karmada 提供了 PropagationPolicy 和 ClusterPropagationPolicy 两种 API 用于资源分发。关于这两种 API 的区别,可参考 此处。
本指南通过解释 API 规范中的每个字段来描述 PropagationPolicy 的配置选项。ClusterPropagationPolicy 与其共享相同的 spec 结构,因此示例对两者均适用。
ResourceSelectors(资源选择器)
resourceSelectors 字段指定应分发哪些资源。必须至少定义一个选择器。
ResourceSelector 通过 API 版本和 Kind 匹配资源,并可选择性地通过名称、标签和命名空间进一步筛选。如果未设置 name 或 labelSelector,它将匹配有效命名空间中(默认为策略的命名空间)给定 APIVersion/Kind 的所有资源。
匹配策略命名空间中的所有资源
如果省略 name 和 labelSelector,选择器将匹配有效命名空间(默认为策略命名空间)中指定 APIVersion/Kind 的所有资源:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: all-deployments
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
clusterNames:
- member1
- member2
这将匹配策略命名空间中的所有 Deployment。
对于 ClusterPropagationPolicy,相同的选择器将匹配所有命名空间中的 Deployment。
按名称匹配
按名称匹配特定资源:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
- member1
这仅匹配策略命名空间中名为 nginx 的 Deployment。
按标签匹配
通过标签选择器匹配资源:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: app-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
labelSelector:
matchLabels:
app: nginx
placement:
clusterAffinity:
clusterNames:
- member1
这将匹配策略命名空间中带有标签 app=nginx 的 Deployment。
PropagateDeps(分发依赖)
propagateDeps 字段控制是否应自动分发依赖资源。
启用时,被分发工作负载引用的资源(例如,Deployment 引用的 ConfigMap 和 Secret)将自动分发,无需在 resourceSelectors 中列出它们。
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
namespace: default
name: nginx
propagateDeps: true
placement:
clusterAffinity:
clusterNames:
- member1
这会将 nginx Deployment 及其引用的依赖项分发到 member1。
Placement(分发位置)
placement 字段指定资源应如何分发到各个集群。它包括集群亲和性、扩散约束和副本调度策略。
Cluster Affinity(集群亲和性)
.spec.placement.clusterAffinity 字段表示调度限制,用于限制可选择哪些集群。如果未指定,任何集群都可以成为调度候选集群。
ClusterAffinity 支持四种过滤机制:
- LabelSelector(标签选择器):按标签过滤集群
- FieldSelector(字段选择器):按字段(provider、region、zone)过滤集群
- ClusterNames(集群名称):显式列出集群名称
- ExcludeClusters(排除集群):显式排除集群名称
当指定多个过滤机制时,它们以逻辑 AND 组合, 这意味着集群必须匹配所有指定条件才能被选中。
clusterAffinity 定义了集群的候选集——它指定哪些集群有资格被选择,但不保证它们都会被选中。调度器会根据各种因素(如调度策略、集群健康状况和资源可用性)从此候选集中进行选择。要严格控制选择多少个集群,请将 spreadConstraints 与 clusterAffinity 结合使用。
例如,如果在 clusterNames 中指定了 10 个集群,但希望确保仅选择 2 个,可将其与 spreadConstraints 结合,使用 spreadByField: cluster 并设置 maxGroups: 2, minGroups: 2。
LabelSelector(标签选择器)
LabelSelector 是按标签选择成员集群的过滤器。它使用 *metav1.LabelSelector 类型。如果它非 nil 且非空,它将过滤候选集以仅包含匹配此过滤器的集群。
PropagationPolicy 可按如下方式配置:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: test-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
labelSelector:
matchLabels:
location: us
这将创建标记为 location=us 的集群候选集。
PropagationPolicy 也可按如下方式配置:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: test-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
labelSelector:
matchExpressions:
- key: location
operator: In
values:
- us
这使用基于集合的选择器过滤候选集,仅包含其 location 标签在 us 中的集群。
有关 matchLabels 和 matchExpressions 的描述,您可以参考支持基于集合的需求的资源。
FieldSelector(字段选择器)
FieldSelector 是按字段选择成员集群的过滤器。如果它非 nil 且非空,它将过滤候选集以仅包含匹配此过滤器的集群。
PropagationPolicy 可按如下方式配置:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
fieldSelector:
matchExpressions:
- key: provider
operator: In
values:
- aws
- key: region
operator: NotIn
values:
- us-west-1
这定义了来自 provider aws 的集群候选集,同时排除 region us-west-1 中的集群。
如果在 fieldSelector 中指定了多个 matchExpressions,集群必须匹配所有 matchExpressions。
matchExpressions 中的 key 现在支持三个值:provider、region 和 zone,它们分别对应 Cluster 对象的 .spec.provider、.spec.region 和 .spec.zone 字段。
matchExpressions 中的 operator 现在支持 In 和 NotIn。
ClusterNames(集群名称)
用户可以设置 ClusterNames 字段来指定选定的集群。
PropagationPolicy 可按如下方式配置:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
clusterNames:
- member1
- member2
这将候选集限制为 member1 和 member2。
ExcludeClusters(排除集群)
显式排除集群被选中:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
exclude:
- member1
- member3
这将从候选集中排除 member1 和 member3。
ClusterAffinities(多个集群组)
clusterAffinities 字段允许定义多个具有回退行为的集群组。clusterAffinity 定义一组选择条件,这些条件一起应用以产生单个候选集群集。clusterAffinities 定义多个有序的条件集(组),这些条件集按顺序评估:调度器尝试第一组,仅当前一组无法满足调度时才回退到下一组。
clusterAffinities 不能与 clusterAffinity 共存。
工作原理
调度器按顺序评估亲和性组:
- 尝试使用第一组进行调度
- 如果第一组不满足调度限制,尝试下一组
- 一个集群可以属于多个组
- 如果没有组满足限制,调度失败
ClusterAffinityTerm
clusterAffinities 中的每个组由一个 ClusterAffinityTerm 定义,包含以下内容:
affinityName:集群组的可读名称- 内联
ClusterAffinity字段,如labelSelector、fieldSelector、clusterNames和exclude:定义该 term 的主集群组 overflowAffinities(可选):附加的有序集群组,仅在同一 term 中的主集群组无法容纳调度时才会被使用
通过 overflowAffinities,可以实现溢出调度场景,例如优先调度到 IDC 集群,当 IDC 资源不足时溢出到云端集群。
由于溢出调度需要感知成员集群的可用资源,目前不支持副本复制模式和静态权重分配与溢出调度组合使用。
overflowAffinities 工作原理

调度器按顺序评估主集群组和溢出集群组:
- 尽可能将副本分配到主集群组。
- 如果主集群组无法容纳所有副本,则尝试将剩余副本分配到溢出集群组。
- 对于每个溢出组,分配的副本数为剩余未分配副本数与该组总可用容量中的较小值。
- 在每个组内,副本根据
placement.replicaScheduling策略分配到各集群。 - 一旦所有副本都能被分配,调度成功。如果评估完所有组后仍有副本未分配, 则此 ClusterAffinityTerm 调度失败,调度器将继续评估 clusterAffinities 中的下一个 ClusterAffinityTerm(如有)。
用例 1:本地集群作为主集群,云集群作为备份
本地数据中心的私有集群可以作为主组,集群提供商提供的托管集群可以作为次要组。调度器会优先调度到主组,仅当主组缺乏资源时才考虑第二组。
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: test-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinities:
- affinityName: local-clusters
clusterNames:
- local-member1
- local-member2
- affinityName: cloud-clusters
clusterNames:
- public-cloud-member1
- public-cloud-member2
这优先选择本地集群,如果它们无法满足调度,则回退到云组。
用例 2:灾难恢复(主集群和备份集群)
集群被组织为主组和备份组。工作负载首先调度到主集群,如果主集群失败则迁移到备份集群。
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: test-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinities:
- affinityName: primary-clusters
clusterNames:
- member1
- member2
- affinityName: backup-clusters
clusterNames:
- member3
- member4
这首先尝试主集群,如果主集群失败,则将工作负载移动到备份组。