Karmada v0.10 版本新特性解析:Resource Interpreter Webhook、动态权重调度与跨集群观测
2026/9/17 20:28:43 网站建设 项目流程

Karmada v0.10 版本新特性解析:Resource Interpreter Webhook、动态权重调度与跨集群观测

【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmada

本文基于 Karmada 官方变更记录 CHANGELOG-0.10.md 展开,系统讲解 v0.10 版本交付的三大核心能力:Resource Interpreter Webhook 框架(让自定义资源获得与原生资源同等的传播能力)、dynamicWeightJob分片调度增强,以及kubectl karmada get跨集群资源观测命令。读完本文,你可以理解自定义资源接入 Karmada 传播体系的完整机制、动态权重复制分摊的计算原理,并掌握从控制面统一观测成员集群工作负载的方法。

一、Karmada v0.10 交付了哪些能力

Karmada v0.10 的版本记录围绕三个主题组织:新特性(What's New)包括 Resource Interpreter Webhook、调度能力增强、跨集群工作负载观测三大块;其他重要变更(Other Notable Changes)则涵盖 estimator 行为调整、对象标签迁移、Bug 修复与可观测性埋点等内容。

从源码结构看,这几块能力分别落在以下模块:

特性仓库中对应的实现位置
Resource Interpreter Webhookpkg/resourceinterpreter/、pkg/webhook/interpreter/
dynamicWeight / Job 分片调度pkg/apis/policy/v1alpha1/propagation_types.go、pkg/scheduler/core/
kubectl karmada getpkg/karmadactl/get/get.go
事件/状态埋点pkg/events/events.go、pkg/apis/work/v1alpha2/binding_types.go

下面按变更记录的原始脉络逐一展开。

二、Resource Interpreter Webhook:教会 Karmada 理解你的自定义资源

2.1 设计动机

在资源(即 resource template)传播到成员集群的过程中,Karmada 会根据资源定义采取行动。例如在构建ResourceBinding阶段,karmada-controller-manager会解析Deployment等资源的replicas字段,而对没有replicas的资源则不做处理。对于 Kubernetes 原生资源,Karmada 内置了解析知识;但对于自定义资源类型(CRD),由于不了解其结构,Karmada 只能把它当作普通资源处理。

v0.10 引入的Resource Interpreter Webhook框架正是解决这一问题的方案:用户可以实现自己的 CRD 插件,在传播流程的各个环节被 Karmada 咨询。借助该框架,CRD 和 CR 将像 Kubernetes 原生资源一样被传播,也就是说所有调度原语(scheduling primitives)都支持自定义资源。官方提案见 Resource Interpreter Webhook Proposal,仓库同时提供了完整的示例工程与工具,位于 examples/customresourceinterpreter/。

2.2 配置 API:ResourceInterpreterWebhookConfiguration

框架受 Kubernetes Admission Webhook 的启发,由两个 API 构成:一个声明启用哪些 webhook 的配置 APIResourceInterpreterWebhookConfiguration(定义在config.karmada.io组),一个声明 Karmada 与 webhook 之间请求/响应格式的消息 APIResourceInterpreterContext

配置对象的核心结构(摘自提案文档):

type ResourceInterpreterWebhookConfiguration struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` // Webhooks 是需要启用的 webhook 及其作用资源与操作的列表。 Webhooks []ResourceInterpreterWebhook `json:"webhooks"` } type ResourceInterpreterWebhook struct { // Name 是 webhook 的完全限定名。 Name string `json:"name"` // ClientConfig 定义如何与 webhook 通信。 ClientConfig admissionregistrationv1.WebhookClientConfig `json:"clientConfig"` // Rules 描述该 webhook 关注的操作和资源。 Rules []RuleWithOperations `json:"rules,omitempty"` // TimeoutSeconds 指定 webhook 超时时间(1~30 秒),默认 10 秒。 TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` // InterpreterContextVersions 是 Webhook 期望的 ResourceInterpreterContext // 版本有序列表,Karmada 会优先使用列表中它支持的第一个版本。 InterpreterContextVersions []string `json:"interpreterContextVersions"` }

其中RuleWithOperations是操作(Operations)与资源(APIGroups/APIVersions/Kinds)的元组,APIGroupsAPIVersionsKinds三个字段都支持*通配(出现*时切片长度必须为 1);核心组的 group 为空,需写成[""]

2.3 消息 API 与操作集合:InterpreterOperation

InterpreterOperation表示 Karmada 在整个传播过程中可能调用 webhook 的请求类型,这也是本框架的扩展点所在:

操作含义
*(InterpreterOperationAll)匹配所有操作
InterpretReplica让 webhook 解释资源声明的副本数(仅适用于带副本声明的资源类型)
ReviseReplica请求 webhook 按目标值修改副本数
InterpretStatus解释如何获取状态(适用于状态不在.status路径的特殊资源)
Prune解释如何将资源模板打包进 Work
Retain请求 webhook 决定期望资源模板中哪些本地变更需要保留(适用于成员集群控制器会回写.spec的资源)
AggregateStatus解释如何把各集群状态聚合回资源模板
InterpretHealth解释如何判断资源的健康状态
InterpretDependency解释资源的依赖关系(如 Deployment 依赖 ConfigMap/Secret),使依赖可随资源一起传播

对应的请求/响应消息ResourceInterpreterContext包含RequestResponse两部分:Request携带UID(用于 Karmada 与 webhook 之间关联日志)、KindNameNamespaceOperation、资源对象Object,以及在特定操作下才填充的ObservedObject(仅Retain操作,来自成员集群的观测对象)、DesiredReplicas(仅ReviseReplica操作)、AggregatedStatus(各集群状态列表)等字段;Response则按需回填ReplicasReplicaRequirementsDependenciesRawStatusHealthy,以及 JSONPatch 格式的Patch(当前仅支持 RFC 6902 的JSONPatch)。

提案中的两条用户故事说明了典型使用场景:

  • 让自定义工作负载参与副本调度:你的自定义资源与Deployment高度相似、带有replica字段,希望通过ReplicaScheduling规则把副本分到多个集群。没有该框架时,Karmada 因不了解结构而无法读取副本数;
  • 自定义本地值保留(retain)策略:成员集群中的控制器会修改资源(如更新.spec中的字段),你希望 Karmada 保留这些变更。没有该框架时,Karmada 可能无法正确保留,导致资源在 Karmada 与你的控制器之间被反复来回修改。

2.4 配置示例与请求/响应示例

下面是一个声明了两个 webhook 的配置示例:foo.example.com服务于foo.example.com组的Foo,实现RetainInterpretHealthbar.example.com服务于bar.example.com组的Bar,实现InterpretDependencyInterpretHealth

apiVersion: config.karmada.io/v1alpha1 kind: ResourceInterpreterWebhookConfiguration metadata: name: example webhooks: - name: foo.example.com rules: - operations: ["Retain", "InterpretHealth"] apiGroups: ["foo.example.com"] apiVersions: ["*"] kinds: ["Foo"] clientConfig: url: https://xxx:443/explore-foo caBundle: {{caBundle}} interpreterContextVersions: ["v1alpha1"] timeoutSeconds: 3 - name: bar.example.com rules: - operations: ["InterpretDependency", "InterpretHealth"] apiGroups: ["bar.example.com"] apiVersions: ["*"] kinds: ["Bar"] clientConfig: url: https://xxx:443/explore-bar caBundle: {{caBundle}} interpreterContextVersions: ["v1alpha1"] timeoutSeconds: 3

InterpretHealth为例,Karmada 发送的请求形如:

apiVersion: config.karmada.io/v1alpha1 kind: ResourceInterpreterContext request: uid: xxx kind: group: foo.example.com version: v1alpha1 kind: Foo name: foo namespace: default operation: InterpretHealth object: <资源的原始数据>

webhook 响应形如:

apiVersion: config.karmada.io/v1alpha1 kind: ResourceInterpreterContext response: uid: xxx # 与请求中的 uid 相同 successful: true healthy: true

2.5 仓库中的实现与示例

从源码结构看,该框架的调用入口在 pkg/resourceinterpreter/interpreter.go,其中:

  • Webhook 解释器的具体实现位于 pkg/resourceinterpreter/customized/webhook/,包含 webhook 配置管理(configmanager/)、请求属性解析(request/)与服务端点解析(serviceresolvers.go);
  • Karmada 对原生资源的默认解释逻辑位于 pkg/resourceinterpreter/default/native/,按操作拆分为 replica.go、revisereplica.go、retain.go、aggregatestatus.go、healthy.go、dependencies.go 与 prune/ 等文件,可以对照各操作逐一理解默认行为;
  • 除了 webhook 方式,仓库还演进出了基于 Lua 声明式的解释器 pkg/resourceinterpreter/customized/declarative/,并对 Argo Workflows、KubeRay、Flux、Volcano 等第三方生态资源内置了定制配置(见 pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/)。

完整的可运行示例见 examples/customresourceinterpreter/:包含示例 CRD 定义 workload.example.io_workloads.yaml、webhook 服务端 examples/customresourceinterpreter/webhook/app/、webhook 配置 karmada-interpreter-webhook-example.yaml 以及配套的资源与 PropagationPolicy,是上手该框架最直接的参考。

三、调度能力显著增强

3.1 dynamicWeight:按可用副本数动态分配权重

v0.10 为PropagationPolicyClusterPropagationPolicy引入了dynamicWeight原语(对应上游 PR #841)。开启后,副本可以按一个动态权重列表划分,每个集群的权重在调度时基于其可用副本数(available replicas)实时计算出来,从而显著平衡各集群的利用率。

在类型定义中,dynamicWeight位于ReplicaSchedulingStrategyWeightPreferenceClusterPreferences)下,源码见 pkg/apis/policy/v1alpha1/propagation_types.go:

// ClusterPreferences describes weight for each cluster or for each group of cluster. type ClusterPreferences struct { // StaticWeightList defines the static cluster weight. StaticWeightList []StaticClusterWeight `json:"staticWeightList,omitempty"` // DynamicWeight specifies the factor to generates dynamic weight list. // If specified, StaticWeightList will be ignored. DynamicWeight DynamicWeightFactor `json:"dynamicWeight,omitempty"` } // DynamicWeightFactor represents the weight factor. // For now only support 'AvailableReplicas'. type DynamicWeightFactor string const ( // DynamicWeightByAvailableReplicas 按可用资源(available replicas)生成集群权重列表。 DynamicWeightByAvailableReplicas DynamicWeightFactor = "AvailableReplicas" )

关键行为约束(可直接从源码注释得到):

  • 当前仅支持AvailableReplicas一种因子,后续可按需扩展;
  • 一旦指定dynamicWeightstaticWeightList将被忽略——动态权重优先于静态权重。

类型定义中的注释给出了官方计算示例,值得完整保留:

调度器选出了 A/B/C 三个集群,需要分配 12 个副本。集群 A 最多可用 6 个副本、B 最多 12 个、C 最多 18 个,则 A:B:C 的权重为 6:12:18(即 1:2:3),最终分配结果为 A: 2、B: 4、C: 6。

结合ReplicaSchedulingStrategy的语义(propagation_types.go):replicaSchedulingTypeDivided时按有效候选集群划分副本;replicaDivisionPreferenceWeighted时按WeightPreference中的权重划分;若只声明Weighted而未配置任何权重,则所有集群等权。一个典型的声明写法为:

spec: replicaScheduling: replicaSchedulingType: Divided replicaDivisionPreference: Weighted weightPreference: dynamicWeight: AvailableReplicas

3.2 Job 分片调度

v0.10 引入了对Job的调度分片支持(对应上游 PR #898):期望多个副本的Job现在可以像Deployment一样被划分到多个集群,这使得在若干小集群上运行超大型 Job 成为可能。从 examples/nginx/ 等示例使用的PropagationPolicy可见,副本调度原语是策略声明层的一部分,Job接入分片调度后同样由这些原语驱动。

四、从 Karmada 控制面观测工作负载

工作负载(如 Deployment)被传播到成员集群后,用户往往还希望获取跨集群的整体状态,尤其是每个Pod的状态。v0.10 为此在kubectl-karmada中引入了get子命令,可以直接从 Karmada 控制面获取部署在成员集群中的各类资源。

变更记录给出的示例输出:

$ kubectl karmada get deployment NAME CLUSTER READY UP-TO-DATE AVAILABLE AGE ADOPTION nginx member2 1/1 1 1 19m Y nginx member1 1/1 1 1 19m Y $ kubectl karmada get pods NAME CLUSTER READY STATUS RESTARTS AGE nginx-6799fc88d8-vzdvt member1 1/1 Running 0 31m nginx-6799fc88d8-l55kk member2 1/1 Running 0 31m

结合源码可以补充两点输出细节。该命令的实现位于 pkg/karmadactl/get/get.go,其输出的ADOPTION列有三个取值(get.go):

取值常量含义
YmanagedByKarmada该资源由 Karmada 控制面托管
NnotManagedByKaramda该资源位于成员集群,但未受 Karmada 控制面管理
-notApplicableKarmada 控制面自身资源,不适用

此外代码中还定义了CLUSTERADOPTION以及针对事件的EVENT附加列(get.go),说明该命令对 Pod、Event 等资源有定制化的列渲染逻辑,而不仅是简单拼接原生kubectl get输出。

五、其他重要变更

变更记录的 "Other Notable Changes" 一节列出了以下值得关注的调整,均附带了上游 PR 编号以便追溯:

  • karmada-scheduler-estimator(PR #777):集群的 Pod 数量成为计算可用副本数时的重要参考因素。从 pkg/estimator/server/ 的 estimator 服务端实现可见,可用副本估算会结合节点可分配资源与现有工作负载共同计算;
  • Work 对象标签迁移(PR #752):此前打在Work对象上的标签resourcebinding.karmada.io/namespaceresourcebinding.karmada.io/nameclusterresourcebinding.karmada.io/name已全部迁移为注解(annotations)。编写基于标签的选择器逻辑时需注意这一兼容性变化;
  • Bug 修复(PR #817):修复了集群 unjoin(退出联邦)对资源状态聚合的影响,避免已退出集群的状态残留污染聚合结果;
  • Work 对象事件(PR #800):引入SyncFailedSyncSucceed事件。在 pkg/events/events.go 中可确认这两个事件原因常量(EventReasonSyncWorkloadFailed = "SyncFailed"EventReasonSyncWorkloadSucceed = "SyncSucceed"),且 pkg/controllers/binding/cluster_resource_binding_controller_test.go 中对事件触发行为有专门的测试断言;
  • ResourceBinding / ClusterResourceBinding 条件(PR #823、PR #825):分别引入ScheduledFullyApplied条件。FullyApplied在 pkg/apis/work/v1alpha2/binding_types.go 中定义为“资源已被完全应用于所有相关集群”的状态条件,且两个 Binding 类型的 printcolumn 中都有对应的FULLYAPPLIED列,kubectl get时可直接查看;
  • Cluster 对象事件(PR #749):引入CreateExecutionNamespaceFailedRemoveExecutionNamespaceFailed事件,用于观测为成员集群创建/删除执行命名空间时的失败;
  • 工作队列指标(PR #831):为karmada-agentkarmada-controller-manager引入workqueue_adds_totalworkqueue_depthworkqueue_longest_running_processor_secondsworkqueue_queue_duration_seconds_bucket等指标,便于监控控制器队列健康度;
  • karmada-scheduler 特性门控(PR #805):调度器引入 feature gates 机制,从 pkg/scheduler/scheduler.go 的调度器组装逻辑可以看出其特性注册入口;
  • karmada-controller-manager 删除行为(PR #970):成员集群中删除资源时默认采用Background删除选项,加快删除速度。

六、小结

Karmada v0.10 是一次围绕"传播能力下沉"与"可观测性补强"的版本:

  1. Resource Interpreter Webhook通过配置 API(ResourceInterpreterWebhookConfiguration)与消息 API(ResourceInterpreterContext)把InterpretReplicaRetainAggregateStatusInterpretDependency等操作开放给用户,使 CRD 获得与原生资源一致的副本调度、状态聚合与健康判断能力;
  2. dynamicWeight: AvailableReplicas让副本按集群实时可用容量加权划分,配合Weighted划分偏好可显著平衡集群利用率;Job 分片则把多副本 Job 纳入了同样的调度原语;
  3. kubectl karmada get让成员集群中的 Deployment、Pod 等资源的跨集群状态可以在控制面统一查看,ADOPTION列明确区分了受管与不受管资源;
  4. 事件(SyncSucceed/SyncFailed)、条件(Scheduled/FullyApplied)与工作队列指标共同补齐了传播链路的观测手段。

如果需要在实际集群中验证这些能力,建议从 examples/customresourceinterpreter/ 的 webhook 示例与 samples/nginx/ 的 PropagationPolicy 示例入手,并配合 docs/command-line-flags/karmadactl_get.md 了解get命令的完整参数。

【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmada

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询