Karmada v1.2 版本解析:Descheduler、跨地域调度、聚合 API 与 karmada-search 深度解读
【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmada
本文基于 Karmada 仓库中的 CHANGELOG-1.2.md 展开,系统梳理 Karmada v1.2.0 的四大核心升级:全新组件karmada-descheduler引入的再调度能力、基于spread-by-region的多地域高可用调度(含ClusterLocality与SpreadConstraint两个调度插件)、全面落地 Aggregated API 后的karmadactl新命令,以及 Alpha 阶段的多集群资源搜索与分析引擎karmada-search。同时结合当前仓库源码,深入剖析这些特性的实现细节,帮助读者理解 v1.2 调度与可观测性能力的设计与落地方式。
一、调度能力与可扩展性的显著提升
1.1 全新组件:karmada-descheduler
v1.2 引入了全新组件karmada-descheduler,用于对历史调度决策进行再平衡。一个典型场景是:当某个集群资源逐渐枯竭后,该集群上的部分副本(Pod)可能处于 Pending 状态而无法拉起。Descheduler 可以将这些 pending 副本驱逐,使karmada-scheduler有机会将它们"重新调度"到资源充足的集群。
从源码看,Descheduler 的核心实现在 pkg/descheduler/descheduler.go。Descheduler结构体持有多组关键依赖:
bindingInformer/bindingLister:监听 Karmada 控制面中的ResourceBinding对象(v1alpha2),即工作负载的调度结果载体;clusterInformer/clusterLister:监听Cluster对象以感知集群状态;schedulerEstimatorCache/estimatorclient:通过 gRPC 连接karmada-scheduler-estimator,在驱逐前向各成员集群的 estimator 校验目标集群的真实可用资源——这是保证"再调度到资源充足集群"这一语义成立的关键环节;unschedulableThreshold与deschedulingInterval:分别控制判定集群不可调度的时间阈值和再调度检查间隔,两者均可由 cmd/descheduler 下的启动参数配置。
其工作对象的选择逻辑在 pkg/descheduler/core/filter.go 中实现,FilterBindings函数会过滤出"可被再调度"的ResourceBinding,需要同时满足两个条件:
- GVK 校验(
validateGVK):当前版本仅支持apps/v1 Deployment(源码中的supportedGVKs白名单); - Placement 校验(
validatePlacement):从 Binding 的 Annotation 中取出 applied placement,且要求副本分配策略为动态均分(IsReplicaDynamicDivided),即只有replicasDivisionMode: Dynamic的工作负载才会被纳入再调度范围。
这一限制值得注意:从源码结构看,v1.2 阶段的 Descheduler 能力聚焦于 Deployment 的动态副本场景,这正是其"驱逐 pending 副本"这一首要用例的最小可用闭环。
1.2 多地域高可用:spread-by-region 与两个调度插件
v1.2 通过新增spread-by-region约束,允许用户按地域(region)维度打散工作负载——例如让副本永远运行在不同的 region 上以获得跨地域容灾能力。
围绕该能力,karmada-scheduler同时引入了两个调度框架插件:
SpreadConstraint:过滤插件
实现位于 pkg/scheduler/framework/plugins/spreadconstraint/spread_constraint.go。其Filter方法遍历 Binding 中 Placement 的SpreadConstraints,逐条校验候选集群是否具备对应属性:
spreadByField: Provider时,要求cluster.Spec.Provider非空;spreadByField: Region时,要求cluster.Spec.Region非空;spreadByField: Zone时,要求cluster.Spec.Zones非空。
任一约束对应的属性缺失,集群即被判定为Unschedulable。可以推断,这一插件与调度框架中更完整的散布打分逻辑配合,共同保证"按 provider/region/zone 打散"的约束在集群选择阶段就被严格执行——集群的Region/Zones等属性来自成员集群注册(join)时采集的元数据。
ClusterLocality:打分插件
实现位于 pkg/scheduler/framework/plugins/clusterlocality/cluster_locality.go。这是一个典型的"偏好已分配集群"的打分插件:若spec.Clusters中已包含该集群(spec.TargetContains(cluster.Name)),则打满分(100),否则打 0 分。其价值在于:当工作负载需要在部分集群上增删副本、或整体重新评估时,调度器倾向于让工作负载"留在原地",减少不必要的跨集群迁移带来的状态扰动(如本地缓存、会话状态等)。
集群故障容忍相关参数
多集群故障切换(failover)机制的增强在 v1.2 中落地了第一阶段,changelog 中给出了两个关键参数:
--cluster-failure-threshold(karmada-controller-manager与karmada-agent均支持):集群故障阈值,默认 30s。只有当集群持续不健康的时间超过该阈值,才会被判定为not-ready,避免瞬时抖动触发误判。当前仓库中该参数确实存在,定义于 cmd/controller-manager/app/options/options.go 和 cmd/agent/app/options/options.go,默认值均为30*time.Second,与 changelog 描述一致。--failover-eviction-timeout(karmada-controller-manager):驱逐的宽限期,默认 5 分钟。若集群not-ready的时间超过该值,控制器会对集群打 taint 作为驱逐指令(changelog 明确注明:taint 的具体驱逐实现计划放在下一个版本落地,属于渐进式演进)。需要说明的是,在当前仓库中该 flag 已被重命名为--graceful-eviction-timeout(见 cmd/controller-manager/app/options/options.go,默认 10 分钟)并演进为更完整的优雅驱逐机制——如果读者当前使用的是 v1.2 之后的代码,应以--graceful-eviction-timeout为准。
二、全面落地 Aggregated API:karmadactl 与 kubectl-karmada 新能力
Aggregated API在 v1.0 中首次引入,允许用户通过单一聚合 API 端点访问 Karmada 纳管的所有集群。v1.2 将其"全面采用",并在此基础上新增了一批karmadactl子命令。
2.1 get 命令同时支持 push 与 pull 模式集群
karmadactl get现在可以列出 push 模式和 pull 模式(成员集群运行karmada-agent)两种纳管方式下的集群资源,并展示集群级状态:
# karmadactl get deployment -n default NAME CLUSTER READY UP-TO-DATE AVAILABLE AGE ADOPTION nginx member1 2/2 2 2 33h N nginx member2 1/1 1 1 4m38s Y podinfo member3 2/2 2 2 27h N其中ADOPTION列标记该工作负载是否为"接管"(adopt)自成员集群的资源,这一能力对应 changelog 中的 bug 修复条目"promote 命令迁移集群级资源失败"(#1766)等围绕 promote 流程的打磨。
2.2 新增 logs / watch / exec 命令
logs:打印指定集群中指定 Pod 的容器日志,命令形如:
# ./karmadactl logs nginx-6799fc88d8-9mpxn -c nginx -C member1 /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf ...-c指定资源命名空间上下文、-C指定目标成员集群,实现了"只面向 Karmada 控制面、按集群下钻查看日志"的运维体验。
watch与exec:与get、logs一样全部走聚合 API。这三个命令在仓库中分别对应 pkg/karmadactl/logs、pkg/karmadactl/watch、pkg/karmadactl/exec 目录下的实现,入口挂载在 pkg/karmadactl/karmadactl.go。
v1.2 同时修复了聚合 API 侧的多个相关问题,使这些命令在长连接场景下可用:
karmada-aggregated-apiserver:修复karmadactl get -w与logs -f的超时问题(#1620);karmada-aggregated-apiserver:修复 exec 报unable to upgrade connection: you must specify at least 1 of stdin, stdout, stderr的错误(#1632)。
三、分布式搜索与分析引擎 karmada-search(Alpha)
v1.2 新引入karmada-search组件,它在后台缓存各成员集群的资源,使用户可以在不直接访问真实集群的情况下检索资源,典型查询示例:
# kubectl get --raw /apis/search.karmada.io/v1alpha1/search/cache/apis/apps/v1/deployments { "apiVersion": "v1", "kind": "List", "metadata": {}, "items": [{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "annotations": { "cluster.karmada.io/name": "member1", }, } } ] }从仓库结构看,该组件的实现规模可观:
- 入口服务在 pkg/search/apiserver.go,由 cmd/karmada-search 拉起;
- 缓存与代理链路位于 pkg/search/proxy/ 与 pkg/search/backendstore/,其中 pkg/search/proxy/framework/plugins/cache/ 目录包含按资源类型组织的缓存插件;
- 资源同步控制器见 pkg/search/controller.go(含 pkg/search/controllers_test.go 的测试覆盖)。
缓存中每项资源都会带有cluster.karmada.io/name等注解标注来源集群(如上例中的member1),这是"多集群资源视图"得以成立的关键元数据。此外karmada-search还支持将缓存资源同步到 Elasticsearch、OpenSearch 等后端存储,从而获得全文检索、按字段/索引检索、按分数排序、按字段排序以及聚合分析等搜索引擎能力——这为多集群场景下"运维大盘、成本分析、合规审计"类需求提供了数据底座。该功能在 v1.2 为 Alpha 阶段,生产使用需自行评估稳定性。
四、Resource Interpreter Webhook 增强:InterpretStatus
v1.2 为 Resource Interpreter Webhook 框架引入了InterpretStatus操作,支持自定义资源的状态聚合逻辑。Karmada 由此可以"学习"如何采集资源——尤其是自定义资源——的状态:例如某个 CRD 的status字段众多,只有接入方最清楚该聚合哪些字段回传给 Karmada,InterpretStatus让这一逻辑完全由用户侧的 webhook 自定义。
源码印证:
- 操作枚举定义于 pkg/apis/config/v1alpha1/resourceinterpreterwebhook_types.go 中的
InterpreterOperationInterpretStatus; - webhook 侧的请求分发在 pkg/resourceinterpreter/customized/webhook/request/resourceinterpretercontext.go,按操作类型(含
InterpretStatus)构造给外部 webhook 的请求上下文; - 与之配套的可配置化声明式解释器(declarative)同样支持该操作,见 pkg/resourceinterpreter/customized/declarative/configurable.go;
- webhook 自身的 HTTP 服务实现在 pkg/webhook/interpreter/(
http.go、webhook.go等)。
此外 v1.2 修复了 "interpreter webhook 返回 nil patch 时karmada-controller-manager发生 panic" 的问题(#1584),并新增了 DaemonSet 与 StatefulSet 的默认 AggregateStatus webhook(#1586),两者都直接服务于状态聚合链路的健壮性。
五、生态集成验证:Kyverno / Gatekeeper / fluxcd
借助 Kubernetes 原生 API,Karmada 能够平滑接入 Kubernetes 生态。v1.2 由社区验证了以下组件在 Karmada 环境下的可用性:
| 组件 | 类别 | 说明 |
|---|---|---|
Kyverno | 策略引擎 | 基于 K8s 原生 API 在 Karmada 集群体系上实施策略治理 |
Gatekeeper | 策略引擎 | 另一套可选的策略引擎方案 |
fluxcd | GitOps | 面向 Helm chart 的 GitOps 工具链 |
由于这些集成全部依赖 Kubernetes 原生 API 而非 Karmada 专有接口,从源码结构看,Karmada 的聚合 API 与常规 API Server 行为兼容性是这些集成的基础。
六、其他值得注意的变更(Other Notable Changes)
6.1 主要 Bug 修复
- karmadactl:修复 legacy secret 场景下的集群 join 失败(#1306);修复
-v 6日志级别不可用(#1426);修复init命令--namespace参数不生效(#1416);支持自定义 namespace(#1449);修复 init 因数据路径未清理而失败(#1455);修复 init 无法读取 KUBECONFIG 环境变量(#1437);修复 init 无法选择默认发行版本(#1456);修复部署karmada-agent时karmada-system命名空间已存在的报错(#1604);修复 controller-manager 参数未遵循自定义 namespace(#1683);修复 promote 资源到 Karmada 时因 nil annotation 导致的 panic(#1759);修复 promote 命令无法迁移集群级资源(#1766);修复控制面配置不在默认路径时karmadactl taint失败(#1825)。 - helm-chart:修复
karmada-agent因权限不足导致安装失败(#1457);修复版本约束跳过 pre-release 的问题(#1444)。 - karmada-controller-manager:修复调度失败时
ResourceBinding可能阻塞入队的问题(#1499);修复 interpreter webhook 返回 nil patch 的 panic(#1584);修复 work 状态更新时 RB/CRB 控制器状态聚合失败(#1513)。 - karmada-aggregated-apiserver:修复
get -w与logs -f的超时问题(#1620);修复 exec 的 connection upgrade 错误(#1632)。
6.2 功能与增强
karmada-controller-manager:新增一系列控制并发能力的参数(--rate-limiter-base-delay、--rate-limiter-max-delay、--rate-limiter-qps、--rate-limiter-bucket-size,#1399)——这类参数同样被引入karmada-agent(#1505),为大规模场景下的控制器吞吐调优提供了抓手。karmada-controller-manager/karmada-scheduler/karmada-agent/karmada-scheduler-estimator:klog 参数分组,提升命令行可读性(#1468、#1491、#1389、#1493)。karmada-controller-manager:修复非调度场景下ResourceBinding/ClusterResourceBinding的FullyApplied条件误标问题(#1512);空ResourceSelector的OverridePolicy现与 nil 一样匹配所有资源(#1706)。karmada-scheduler:集群注销(unregister)后,其上工作负载可以被重新调度(#1383)——这条与 Descheduler 一起构成了 v1.2"调度决策可修正"的完整图景。karmada-webhook:新增--tls-cert-file-name与--tls-private-key-file-name指定服务端证书与私钥(#1464)。karmadactl:新增--context指定上下文(#1748);init子命令新增--kube-image-mirror-country与--kube-image-registry,方便中国大陆用户拉取镜像(#1764);新增deinit子命令卸载 Karmada(#1337)。- 为 Karmada API 引入 Swagger 文档(#1401),对应仓库中的 api/openapi-spec/swagger.json。
6.3 依赖与废弃
- 基础镜像 alpine 升级至 v3.15.1(#1519)。
- 废弃项:
karmada-controller-manager的 HPA 控制器默认禁用(#1580)——v1.2 时代 HPA 聚合能力处于调整期,默认关闭以避免错误行为;karmada-aggregated-apiserver移除了 v1.1 中已废弃的--karmada-config与--master参数(#1834)。
七、版本小结
Karmada v1.2.0 的主线清晰:以Descheduler + 跨地域散布约束 + 故障容忍参数强化调度侧的"长期正确性"(决策可以修正、可以跨地域打散、可以在集群故障时容忍抖动);以Aggregated API 全面落地 + logs/watch/exec强化"面向单一入口的多集群运维体验";以karmada-search(Alpha)+ InterpretStatus webhook补齐多集群资源的"检索与分析"和"自定义状态聚合"两块拼图。若你正在评估从 v1.1 升级,建议重点关注 HPA 控制器默认禁用的行为变化与--failover-eviction-timeout在后续版本中的演进;若从源码角度继续深挖,入口可依次从 pkg/descheduler/、pkg/scheduler/framework/plugins/、pkg/search/ 与 pkg/resourceinterpreter/customized/webhook/ 四个目录切入,均配有对应的单元测试可供验证。
【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmada
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考