问题描述
一般情况下,工作负载类资源一旦被调度,其调度结果通常会保持惰性,不会轻易改变副本分布状态。即使通过修改资源模板中的副本数或 PropagationPolicy 的 Placement 来触发重新调度,系统也只会在必要时进行最小化的调整,以最大程度地减少对系统的影响。
然而,在某些情况下,用户可能希望能够主动触发全新的重调度,完全忽略过去的分配结果,并在集群之间建立全新的副本分布状态。
应用场景
1.在集群故障迁移的情况下,副本分布在 member1 和 member2 两个集群中,但如果 member1 集群故障,副本将全部迁移到 member2 集群。作为集群管理员,我希望在 member1 集群恢复时,副本重新分配到两个集群,一方面重新利用 member1 集群的资源,另一方面也为了保证集群高可用性。
2.在应用级别故障迁移场景,因为集群资源稀缺,低优先级的应用程序可能会被抢占,导致其从多个集群缩减到单个集群。 作为用户,我希望当集群资源充足时,低优先级应用程序的副本可以重新分布到多个集群,以确保应用程序的高可用性。
3、对于“聚合”调度类型,由于资源约束,副本仍然可能分布到多个集群中。作为用户,我希望当任何集群具有足够的资源来容纳所有副本时,副本能以聚合策略重新分配,从而使应用程序更好地满足实际业务需求。
4.在灾备场景中,当主集群故障时,副本会从主集群迁移到备集群。作为集群管理员,我希望在主集群恢复时,副本可以迁回主集群,以实现以下目的:
- 恢复到灾备模式,确保集群联邦的高可用和稳定性。
- 备集群往往成本更高,节省备集群的成本
单个资源的重调度
在 Karmada 中,WorkloadRebalancer 是一个用于 手动触发工作负载(如 Deployment、StatefulSet)重新调度 的 CRD(自定义资源)。它允许管理员在不修改原有 PropagationPolicy 的情况下,强制将 Pod 副本重新分配到更合适的成员集群。
- 手动触发重调度:针对单个资源(如 Deployment)进行副本重新分配。
- 动态调整副本分布:基于当前集群资源状况,优化副本分布。
- 无需修改原有策略:不影响已有的 PropagationPolicy 或 ClusterResourceBinding。
apiVersion: policy.karmada.io/v1alpha1
kind: WorkloadRebalancer
metadata:
name: nginx-rebalancer # 自定义名称
spec:
workload:
apiVersion: apps/v1
kind: Deployment
name: nginx-de-re # 要重调度的 Deployment 名称
namespace: default # 资源所在命名空间
调用过程:
- Karmada 调度器 会重新计算副本分配策略:
- 调用 karmada-scheduler-estimator 获取各集群当前可用资源。
- 结合 PropagationPolicy 的 replicaScheduling 规则(如动态权重 dynamicWeight: AvailableReplicas)。
- 调整副本分布:
- 从资源不足的集群移除副本。
- 在资源充足的集群增加副本。
批量资源的重调度
# rebatch-rebalancer.yaml
apiVersion: policy.karmada.io/v1alpha1
kind: WorkloadRebalancer
metadata:
name: rebatch-deployments
spec:
workloadList:
- apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
namespace: default
- apiVersion: apps/v1
kind: Deployment
name: redis-deployment
namespace: default
- apiVersion: apps/v1
kind: StatefulSet
name: mysql-statefulset
namespace: db
WorkloadRebalancer 的修改
WorkloadRebalancer 也支持修改,其准则是:
- 如果 spec 中新增一个 workload,则对其履行重调度并将其添加到 status 列表中
- 如果从 spec 中删除一个 workload,若该 workload 已成功,则保留在 status 列表中,若未成功则移除
- 如果一个 spec 中的 workload 被修改,等价于先删除一个旧的 workload 再插入一个新的 workload
自动清理 WorkloadRebalancer
您可以使用
spec.ttlSecondsAfterFinished 来指定 WorkloadRebalancer 资源执行完成后将在何时执行自动清理 (执行完成是指每个目标工作负载都以 Successful 或 Failed 的结果完成运行)。
执行自动清理的准则是:
- 如果设置了此字段,在 WorkloadRebalancer 完成后的 ttlSecondsAfterFinished 秒,它将被自动删除
- 如果未设置此字段,则 WorkloadRebalancer 不会被自动删除
- 如果将此字段设置为零,则 WorkloadRebalancer 将在完成后立即被删除
apiVersion: apps.karmada.io/v1alpha1
kind: WorkloadRebalancer
metadata:
name: demo
spec:
ttlSecondsAfterFinished: 60
workloads:
- apiVersion: apps/v1
kind: Deployment
name: demo-deploy
namespace: default
多集群故障迁移
在多云多集群场景中,为了提高业务的高可用性,用户工作负载可能会被部署在多个不同的集群中。在Karmada中,当集群发生故障或是用户不希望在某个集群上继续运行工作负载时,集群状态将被标记为不可用,并被添加上一些污点。taint-manager检测到集群故障之后,会从这些故障集群中驱逐工作负载,被驱逐的工作负载将被调度至其他最适合的集群,从而达成故障迁移的目的,保证了用户业务的可用性与连续性。
应用场景:
1.管理员部署一个离线业务,并将业务pod事列分发到多个集群。突然某个集群发生故障,管理员希望karmada能够把故障集群上的pod实例迁移到其他条件适合的集群中去
2.普通用户通过kamada平面 在某个集群上部署一个在线业务,业务包括数据库事列,服务器实例,配置文件等,服务通过控制面上的ELB对外暴漏,此时一个集群发生故障,用户把整个业务迁移到另一个情况较合适的集群上,业务迁移期间需要保证服务不断服
3.管理员将某个集群进行升级,作为基础设施的容器网络、存储等发生了改变,管理员希望在集群升级之前把当前集群上的应用迁移到其他适合的集群中去,业务迁移期间需要保证服务不断服。
迁移过程:
用户在Karmada中加入了三个集群,分别为:member1、member2和member3。然后在karmada控制面部署了一个名为foo,且副本数为2的Deployment,并通过PropagationPolicy将其分发到了集群member1和member2上。
当集群member1发生故障之后,其上的Pod实例将被驱逐,然后被迁移到集群member2或是集群member3中,这个不同的迁移行为可以通过
PropagationPolicy/ClusterPropagationPolicy的副本调度策略ReplicaSchedulingStrategy来控制。
开启属性
用户可以通过启用 Failover 特性开关来开启故障迁移特性。Failover 特性开关目前默认关闭,用户应明确启用以避免意外事件。您可以按照如下配置在
karmada-controller-manager 组件中启用 Failover 特性开关:
--feature-gates=Failover=true
此外,如果用户启用了 GracefulEvction 特性,故障迁移过程将变得十分平滑且优雅,也就是说,工作负载的驱逐将被推迟到工作负载在新群集上启动或达到最大宽限期之后才被执行。
优雅驱逐功能由 Failover 和 GracefulEviction 特性开关控制。GracefulEviction 特性开关目前默认启用。你可以按照如下配置启用
karmada-controller-manager 组件的 Failover 和 GracefulEviction 特性门控:
集群故障判定:
在 Karmada 中,对集群的心跳探测有两种方式:
- 集群状态收集,更新集群的 .status 字段(包括 Push 和 Pull 两种模式);
- Karmada 控制面中 karmada-cluster 命名空间内的 Lease 对象,每个 Pull 模式集群都有一个关联的 Lease 对象。
集群状态收集
对于 Push 模式集群,Karmada 控制面中的 clusterStatus 控制器将定期执行执行集群状态的收集任务; 对于 Pull 模式集群,集群中部署的 karmada-agent 组件负责创建并定期更新集群的 .status 字段。
上述集群状态的定期更新任务可以通过
--cluster-status-update-frequency 标签进行配置(默认值为 10 秒)。
集群的 Ready 条件在满足以下条件时将会被设置为 False:
- 集群持续一段时间无法访问;
- 集群健康检查响应持续一段时间不正常。
上述持续时间间隔可以通过
--cluster-failure-threshold 标签进行配置(默认值为 30 秒)。
故障迁移:
当Karmada检测到故障群集不再被
PropagationPolicy/ClusterPropagationPolicy分发策略容忍时,该集群将被从资源调度结果中删除,随后,Karmada调度器将重新调度相关工作负载。
重调度的过程有以下几个限制:
- 对于每个重调度的工作负载,其仍然需要满足PropagationPolicy/ClusterPropagationPolicy的约束,如ClusterAffinity或SpreadConstraints。
- 应用初始调度结果中健康的集群在重调度过程中仍将被保留。
Duplicated调度类型
对于Duplicated调度类型,当集群故障之后进行重新调度,满足分发策略限制的候选集群数量大于等于故障集群数量时,调度将继续执行,否则不执行。其中候选集群是指在本次调度过程中,区别与已调度的集群,新计算出的集群调度结果。
以Deployment资源为例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
---
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
- member1
- member2
- member3
- member5
spreadConstraints:
- maxGroups: 2
minGroups: 2
replicaScheduling:
replicaSchedulingType: Duplicated
假设有5个成员集群,初始调度结果在member1和member2集群中。当member2集群发生故障,将触发调度器重调度。
需要注意的是,重调度不会删除原本状态为Ready的集群member1上的工作负载。在其余3个集群中,只有member3和member5匹配clusterAffinity策略。
由于分发约束的限制,最后应用调度的结果将会是[member1, member3]或[member1, member5]。
Divided调度类型
对于Divided调度类型,Karmada调度器将尝试将应用副本迁移到其他健康的集群中去。
以Deployment资源为例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
---
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
- member1
- member2
replicaScheduling:
replicaDivisionPreference: Weighted
replicaSchedulingType: Divided
weightPreference:
staticWeightList:
- targetCluster:
clusterNames:
- member1
weight: 1
- targetCluster:
clusterNames:
- member2
weight: 2
Karmada调度器将根据权重表weightPreference来划分应用副本。初始调度结果中,member1集群上有1个副本,member2集群上有2个副本。
当member1集群故障之后,将触发重调度,最后的调度结果将会是member2集群上有3个副本。
优雅故障迁移
为了防止集群故障迁移过程中服务发生中断,Karmada需要确保故障集群中应用副本的删除动作延迟到应用副本在新集群上可用之后才执行。
ResourceBinding/ClusterResourceBinding中增加了GracefulEvictionTasks字段来表示优雅驱逐任务队列。
当故障集群被taint-manager从资源调度结果中删除时,它将被添加到优雅驱逐任务队列中。
gracefulEvction控制器负责处理优雅驱逐任务队列中的任务。在处理过程中,gracefulEvction控制器逐个评估优雅驱逐任务队列中的任务是否可以从队列中移除。判断条件如下:
- 检查当前资源调度结果中资源的健康状态。如果资源健康状态为健康,则满足条件。
- 检查当前任务的等待时长是否超过超时时间,超时时间可以通过graceful-evction-timeout标志配置(默认为10分钟)。如果超过,则满足条件。