Karmada-Work 组件详解

[复制链接]
发表于 2026-1-14 21:37:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Karmada Work 组件详解

目次

一、使用配景

1.1 为什么须要 Work 资源?

Work 是 Karmada 资源传播链路中的实验载体,它是 ResourceBinding 的卑鄙,负责将资源模板实际分发到成员集群。
焦点作用


  • 资源分发载体:承载要分发到成员集群的资源清单(Manifests)
  • 集群隔离:每个 Work 对象对应一个目标集群,实现集群级别的资源隔离
  • 状态网络:记载资源在成员集群中的实际状态(Applied、Progressing、Available、Degraded)
  • 实验控制:支持停息分发(SuspendDispatching)、保存资源(PreserveResourcesOnDeletion)等控制本领
1.2 在资源传播链路中的位置
  1. 资源模板 (Deployment)
  2.     ↓
  3. PropagationPolicy (传播策略)
  4.     ↓
  5. ResourceBinding (RB) - 绑定关系
  6.     ↓
  7. Work (每个目标集群一个) ⭐
  8.     ↓
  9. 成员集群中的实际资源 (Deployment)
复制代码
关键关系

  • 1 个 ResourceBindingN 个 Work(N = 目标集群数目)
  • 1 个 Work1 个成员集群
  • 1 个 Work1 个或多个资源清单(Manifests)
1.3 Work 的定名空隔断离机制

Work 对象存储在 ExecutionSpace 定名空间中,每个成员集群对应一个 ExecutionSpace:
  1. karmada-es-member1/  ← 成员集群 member1 的 Work
  2.     ├── work-deployment-nginx
  3.     └── work-service-nginx
  4. karmada-es-member2/  ← 成员集群 member2 的 Work
  5.     ├── work-deployment-nginx
  6.     └── work-service-nginx
复制代码
定名规则:karmada-es-{cluster-name}
二、Work API 界说

2.1 根本布局

Work 是一个定名空间级(NamespaceScoped)的 CRD 资源,界说在 pkg/apis/work/v1alpha1/work_types.go:
  1. // Work defines a list of resources to be deployed on the member cluster.
  2. type Work struct {
  3.     metav1.TypeMeta   `json:",inline"`
  4.     metav1.ObjectMeta `json:"metadata,omitempty"`
  5.     // Spec represents the desired behavior of Work.
  6.     Spec WorkSpec `json:"spec"`
  7.     // Status represents the status of PropagationStatus.
  8.     Status WorkStatus `json:"status,omitempty"`
  9. }
复制代码
2.2 WorkSpec - 盼望状态
  1. type WorkSpec struct {
  2.     // Workload represents the manifest workload to be deployed on managed cluster.
  3.     Workload WorkloadTemplate `json:"workload,omitempty"`
  4.     // SuspendDispatching controls whether dispatching should be suspended.
  5.     // true means stop propagating to the corresponding member cluster.
  6.     SuspendDispatching *bool `json:"suspendDispatching,omitempty"`
  7.     // PreserveResourcesOnDeletion controls whether resources should be preserved
  8.     // on the member cluster when the Work object is deleted.
  9.     PreserveResourcesOnDeletion *bool `json:"preserveResourcesOnDeletion,omitempty"`
  10. }
复制代码
焦点字段阐明
字段范例阐明WorkloadWorkloadTemplate要摆设的资源清单列表SuspendDispatching*bool是否停息分发(true 时 Execution Controller 不会应用资源)PreserveResourcesOnDeletion*boolWork 删除时是否保存成员集群中的资源2.3 WorkloadTemplate - 资源清单模板
  1. type WorkloadTemplate struct {
  2.     // Manifests represents a list of Kubernetes resources to be deployed.
  3.     Manifests []Manifest `json:"manifests,omitempty"`
  4. }
  5. type Manifest struct {
  6.     runtime.RawExtension `json:",inline"`  // 任意 Kubernetes 资源的 JSON
  7. }
复制代码
Manifest 内容:可以是任何 Kubernetes 资源(Deployment、Service、ConfigMap 等)的 JSON 序列化。
2.4 WorkStatus - 实际状态
  1. type WorkStatus struct {
  2.     // Conditions contain the different condition statuses for this work.
  3.     Conditions []metav1.Condition `json:"conditions,omitempty"`
  4.     // ManifestStatuses contains running status of manifests in spec.
  5.     ManifestStatuses []ManifestStatus `json:"manifestStatuses,omitempty"`
  6. }
复制代码
Condition 范例
Condition 范例阐明Applied资源是否已乐成应用到成员集群Progressing资源是否正在应用过程中Available资源是否在成员集群中存在Degraded资源状态是否非常Dispatching分发是否被停息ManifestStatus:记载每个 Manifest 的具体状态:
  1. type ManifestStatus struct {
  2.     Identifier ResourceIdentifier `json:"identifier"`  // 资源标识
  3.     Status     *runtime.RawExtension `json:"status,omitempty"`  // 资源状态
  4.     Health     ResourceHealth `json:"health,omitempty"`  // 健康状态
  5. }
复制代码
2.5 完备示例
  1. apiVersion: work.karmada.io/v1alpha1
  2. kind: Work
  3. metadata:
  4.   name: work-deployment-nginx
  5.   namespace: karmada-es-member1
  6.   labels:
  7.     resourcebinding.karmada.io/name: deployment-nginx
  8.     resourcebinding.karmada.io/namespace: default
  9.   finalizers:
  10.     - execution.karmada.io/execution-controller
  11. spec:
  12.   workload:
  13.     manifests:
  14.     - apiVersion: apps/v1
  15.       kind: Deployment
  16.       metadata:
  17.         name: nginx
  18.         namespace: default
  19.         labels:
  20.           app: nginx
  21.           resource.karmada.io/managed-by: karmada
  22.         annotations:
  23.           work.karmada.io/name: work-deployment-nginx
  24.           work.karmada.io/namespace: karmada-es-member1
  25.       spec:
  26.         replicas: 3
  27.         selector:
  28.           matchLabels:
  29.             app: nginx
  30.         template:
  31.           metadata:
  32.             labels:
  33.               app: nginx
  34.           spec:
  35.             containers:
  36.             - name: nginx
  37.               image: nginx:1.21
  38. status:
  39.   conditions:
  40.   - type: Applied
  41.     status: "True"
  42.     reason: AppliedSuccessful
  43.     message: Manifest has been successfully applied
  44.   - type: Available
  45.     status: "True"
  46.     reason: Available
  47.     message: All resources of the Work exists on the managed cluster
  48.   manifestStatuses:
  49.   - identifier:
  50.       ordinal: 0
  51.       group: apps
  52.       version: v1
  53.       kind: Deployment
  54.       resource: deployments
  55.       namespace: default
  56.       name: nginx
  57.     health: Healthy
  58.     status:
  59.       replicas: 3
  60.       readyReplicas: 3
  61.       availableReplicas: 3
复制代码
三、使用方式

3.1 Work 的创建方式

Work 通常由 Binding Controller 自动创建,用户不须要手动创建。但相识其创建过程有助于理崩溃系:
自动创建流程


  • 用户创建资源模板
  1. kubectl create deployment nginx --image=nginx:1.21
复制代码

  • 用户创建 PropagationPolicy
  1. apiVersion: policy.karmada.io/v1alpha1
  2. kind: PropagationPolicy
  3. metadata:
  4.   name: nginx-propagation
  5. spec:
  6.   resourceSelectors:
  7.   - apiVersion: apps/v1
  8.     kind: Deployment
  9.     name: nginx
  10.   placement:
  11.     clusterAffinity:
  12.       clusterNames:
  13.       - member1
  14.       - member2
复制代码

  • Detector 创建 ResourceBinding
  • Scheduler 为 ResourceBinding 选择集群
  • Binding Controller 创建 Work(每个目标集群一个)
手动检察 Work
  1. # 查看所有 Work
  2. kubectl get work -A
  3. # 查看特定集群的 Work
  4. kubectl get work -n karmada-es-member1
  5. # 查看 Work 详情
  6. kubectl get work work-deployment-nginx -n karmada-es-member1 -o yaml
  7. # 查看 Work 状态
  8. kubectl describe work work-deployment-nginx -n karmada-es-member1
复制代码
3.2 控制 Work 的活动

停息分发(SuspendDispatching)

通过设置 spec.suspendDispatching: true,可以停息 Work 的分发:
  1. apiVersion: work.karmada.io/v1alpha1
  2. kind: Work
  3. metadata:
  4.   name: work-deployment-nginx
  5.   namespace: karmada-es-member1
  6. spec:
  7.   suspendDispatching: true  # 暂停分发
  8.   workload:
  9.     manifests:
  10.     - ...
复制代码
结果

  • Execution Controller 不会应用资源到成员集群
  • 已存在的资源不会被删除
  • 状态网络仍然继续
保存资源(PreserveResourcesOnDeletion)

通过设置 spec.preserveResourcesOnDeletion: true,可以在删除 Work 时保存成员集群中的资源:
  1. apiVersion: work.karmada.io/v1alpha1
  2. kind: Work
  3. metadata:
  4.   name: work-deployment-nginx
  5.   namespace: karmada-es-member1
  6. spec:
  7.   preserveResourcesOnDeletion: true  # 删除 Work 时保留资源
  8.   workload:
  9.     manifests:
  10.     - ...
复制代码
结果

  • 删除 Work 时,成员集群中的资源不会被删除
  • 实用于须要手动管理资源的场景
3.3 监控 Work 状态

检察 Work 状态
  1. # 查看 Work 的 Condition
  2. kubectl get work work-deployment-nginx -n karmada-es-member1 \
  3.   -o jsonpath='{.status.conditions[*].type}:{.status.conditions[*].status}'
  4. # 查看 Work 的 Manifest 状态
  5. kubectl get work work-deployment-nginx -n karmada-es-member1 \
  6.   -o jsonpath='{.status.manifestStatuses[*].health}'
复制代码
常见状态

状态阐明处理惩罚方式Applied=True资源已乐成应用正常Applied=False资源应用失败查抄 Execution Controller 日记Available=True资源在集群中存在正常Available=False资源在集群中不存在查抄成员集群状态Degraded=True资源状态非常查抄资源康健状态3.4 故障排查

Work 未应用
  1. # 1. 检查 Work 是否存在
  2. kubectl get work -n karmada-es-member1
  3. # 2. 检查 Work 的 SuspendDispatching
  4. kubectl get work work-deployment-nginx -n karmada-es-member1 \
  5.   -o jsonpath='{.spec.suspendDispatching}'
  6. # 3. 检查 Execution Controller 日志
  7. kubectl logs -n karmada-system deployment/karmada-controller-manager \
  8.   -c karmada-controller-manager | grep execution
  9. # 4. 检查成员集群连接
  10. kubectl get cluster member1 -o yaml
复制代码
Work 状态未同步
  1. # 1. 检查 Work Status Controller 日志
  2. kubectl logs -n karmada-system deployment/karmada-controller-manager \
  3.   -c karmada-controller-manager | grep work-status
  4. # 2. 检查成员集群中的资源是否存在
  5. kubectl --context member1 get deployment nginx
  6. # 3. 检查 Work 的 Manifest 内容
  7. kubectl get work work-deployment-nginx -n karmada-es-member1 \
  8.   -o jsonpath='{.spec.workload.manifests[0]}' | jq
复制代码
四、源码原理

4.1 Work 的创建流程

4.1.1 Binding Controller 创建 Work

位置:pkg/controllers/binding/binding_controller.go
  1. // syncBinding will sync resourceBinding to Works.
  2. func (c *ResourceBindingController) syncBinding(ctx context.Context, binding *workv1alpha2.ResourceBinding) (controllerruntime.Result, error) {
  3.     // 1. 获取资源模板
  4.     workload, err := helper.FetchResourceTemplate(ctx, c.DynamicClient, c.InformerManager, c.RESTMapper, binding.Spec.Resource)
  5.    
  6.     // 2. 为每个目标集群创建 Work
  7.     err = ensureWork(ctx, c.Client, c.ResourceInterpreter, workload, c.OverrideManager, binding, apiextensionsv1.NamespaceScoped)
  8.    
  9.     return controllerruntime.Result{}, err
  10. }
复制代码
4.1.2 ensureWork 函数详解

位置:pkg/controllers/binding/common.go
  1. func ensureWork(
  2.     ctx context.Context,
  3.     c client.Client,
  4.     resourceInterpreter resourceinterpreter.ResourceInterpreter,
  5.     workload *unstructured.Unstructured,
  6.     overrideManager overridemanager.OverrideManager,
  7.     binding metav1.Object,
  8.     scope apiextensionsv1.ResourceScope,
  9. ) error {
  10.     bindingSpec := getBindingSpec(binding, scope)
  11.     targetClusters := mergeTargetClusters(bindingSpec.Clusters, bindingSpec.RequiredBy)
  12.    
  13.     // 为每个目标集群创建 Work
  14.     for i := range targetClusters {
  15.         targetCluster := targetClusters[i]
  16.         clonedWorkload := workload.DeepCopy()
  17.         
  18.         // 1. 确定 Work 的命名空间(ExecutionSpace)
  19.         workNamespace := names.GenerateExecutionSpaceName(targetCluster.Name)
  20.         
  21.         // 2. 调整副本数(如果适用)
  22.         if bindingSpec.IsWorkload() {
  23.             if resourceInterpreter.HookEnabled(clonedWorkload.GroupVersionKind(), configv1alpha1.InterpreterOperationReviseReplica) {
  24.                 clonedWorkload, err = resourceInterpreter.ReviseReplica(clonedWorkload, int64(targetCluster.Replicas))
  25.             }
  26.         }
  27.         
  28.         // 3. 应用 OverridePolicy
  29.         cops, ops, err := overrideManager.ApplyOverridePolicies(clonedWorkload, targetCluster.Name)
  30.         
  31.         // 4. 构建 Work 元数据
  32.         workMeta := metav1.ObjectMeta{
  33.             Name:        names.GenerateWorkName(clonedWorkload.GetKind(), clonedWorkload.GetName(), clonedWorkload.GetNamespace()),
  34.             Namespace:   workNamespace,
  35.             Finalizers:  []string{util.ExecutionControllerFinalizer},
  36.             Labels:      workLabel,
  37.             Annotations: annotations,
  38.         }
  39.         
  40.         // 5. 创建或更新 Work
  41.         err = ctrlutil.CreateOrUpdateWork(ctx, c, workMeta, clonedWorkload, ...)
  42.     }
  43.    
  44.     return errors.NewAggregate(errs)
  45. }
复制代码
关键步调

  • 遍历目标集群:为 ResourceBinding 中的每个目标集群创建一个 Work
  • 克隆资源模板:为每个集群创建独立的资源副本
  • 调解副本数:根据调治结果调解副本数(Divided 模式)
  • 应用 OverridePolicy:应用集群特定的设置覆盖
  • 创建 Work:调用 CreateOrUpdateWork 创建或更新 Work
4.1.3 CreateOrUpdateWork 函数详解

位置:pkg/controllers/ctrlutil/work.go
  1. func CreateOrUpdateWork(ctx context.Context, c client.Client, workMeta metav1.ObjectMeta, resource *unstructured.Unstructured, options ...WorkOption) error {
  2.     resource = resource.DeepCopy()
  3.    
  4.     // 1. 设置标签和注解
  5.     util.MergeLabel(resource, util.ManagedByKarmadaLabel, util.ManagedByKarmadaLabelValue)
  6.     util.MergeAnnotation(resource, workv1alpha2.ResourceTemplateUIDAnnotation, string(resource.GetUID()))
  7.     util.MergeAnnotation(resource, workv1alpha2.WorkNameAnnotation, workMeta.Name)
  8.     util.MergeAnnotation(resource, workv1alpha2.WorkNamespaceAnnotation, workMeta.Namespace)
  9.    
  10.     // 2. 清理无关字段
  11.     err := prune.RemoveIrrelevantFields(resource, prune.RemoveJobTTLSeconds)
  12.    
  13.     // 3. 构建 Work 对象
  14.     work := &workv1alpha1.Work{
  15.         ObjectMeta: workMeta,
  16.     }
  17.     applyWorkOptions(work, options)
  18.    
  19.     // 4. 序列化资源为 JSON
  20.     workloadJSON, err := json.Marshal(resource)
  21.    
  22.     // 5. 创建或更新 Work
  23.     err = retry.RetryOnConflict(retry.DefaultRetry, func() (err error) {
  24.         operationResult, err = controllerutil.CreateOrUpdate(ctx, c, runtimeObject, func() error {
  25.             runtimeObject.Spec.Workload = workv1alpha1.WorkloadTemplate{
  26.                 Manifests: []workv1alpha1.Manifest{
  27.                     {
  28.                         RawExtension: runtime.RawExtension{
  29.                             Raw: workloadJSON,
  30.                         },
  31.                     },
  32.                 },
  33.             }
  34.             return nil
  35.         })
  36.         return err
  37.     })
  38.    
  39.     return nil
  40. }
复制代码
关键利用

  • 标记资源:为资源添加 Karmada 管理标签和注解
  • 清算字段:移除不须要同步的字段(如 status、metadata.uid 等)
  • 序列化:将资源序列化为 JSON,存储在 spec.workload.manifests 中
  • 幂等更新:使用 CreateOrUpdate 确保幂等性
4.2 Execution Controller 实验 Work

4.2.1 Reconcile 流程

位置:pkg/controllers/execution/execution_controller.go
  1. func (c *Controller) Reconcile(ctx context.Context, req controllerruntime.Request) (controllerruntime.Result, error) {
  2.     // 1. 获取 Work
  3.     work := &workv1alpha1.Work{}
  4.     if err := c.Client.Get(ctx, req.NamespacedName, work); err != nil {
  5.         return controllerruntime.Result{}, err
  6.     }
  7.    
  8.     // 2. 获取集群名称
  9.     clusterName, err := names.GetClusterName(work.Namespace)
  10.    
  11.     // 3. 获取 Cluster 对象
  12.     cluster, err := util.GetCluster(c.Client, clusterName)
  13.    
  14.     // 4. 处理删除
  15.     if !work.DeletionTimestamp.IsZero() {
  16.         if err := c.handleWorkDelete(ctx, work, cluster); err != nil {
  17.             return controllerruntime.Result{}, err
  18.         }
  19.         return c.removeFinalizer(ctx, work)
  20.     }
  21.    
  22.     // 5. 检查是否暂停分发
  23.     if util.IsWorkSuspendDispatching(work) {
  24.         return controllerruntime.Result{}, nil
  25.     }
  26.    
  27.     // 6. 检查集群是否就绪
  28.     if !util.IsClusterReady(&cluster.Status) {
  29.         return controllerruntime.Result{}, fmt.Errorf("cluster(%s) not ready", cluster.Name)
  30.     }
  31.    
  32.     // 7. 同步 Work 到集群
  33.     return c.syncWork(ctx, clusterName, work)
  34. }
复制代码
4.2.2 syncWork 函数详解
  1. func (c *Controller) syncWork(ctx context.Context, clusterName string, work *workv1alpha1.Work) (controllerruntime.Result, error) {
  2.     start := time.Now()
  3.     err := c.syncToClusters(ctx, clusterName, work)
  4.     metrics.ObserveSyncWorkloadLatency(err, start)
  5.    
  6.     if err != nil {
  7.         msg := fmt.Sprintf("Failed to sync work(%s/%s) to cluster(%s), err: %v", work.Namespace, work.Name, clusterName, err)
  8.         c.EventRecorder.Event(work, corev1.EventTypeWarning, events.EventReasonSyncWorkloadFailed, msg)
  9.         return controllerruntime.Result{}, err
  10.     }
  11.    
  12.     msg := fmt.Sprintf("Sync work(%s/%s) to cluster(%s) successful.", work.Namespace, work.Name, clusterName)
  13.     c.EventRecorder.Event(work, corev1.EventTypeNormal, events.EventReasonSyncWorkloadSucceed, msg)
  14.     return controllerruntime.Result{}, nil
  15. }
复制代码
4.2.3 syncToClusters 函数详解
  1. func (c *Controller) syncToClusters(ctx context.Context, clusterName string, work *workv1alpha1.Work) error {
  2.     var errs []error
  3.     syncSucceedNum := 0
  4.    
  5.     // 遍历 Work 中的所有 Manifest
  6.     for _, manifest := range work.Spec.Workload.Manifests {
  7.         workload := &unstructured.Unstructured{}
  8.         err := workload.UnmarshalJSON(manifest.Raw)
  9.         if err != nil {
  10.             errs = append(errs, err)
  11.             continue
  12.         }
  13.         
  14.         // 创建或更新资源
  15.         if err = c.tryCreateOrUpdateWorkload(ctx, clusterName, workload); err != nil {
  16.             errs = append(errs, err)
  17.             continue
  18.         }
  19.         syncSucceedNum++
  20.     }
  21.    
  22.     // 更新 Applied Condition
  23.     if len(errs) > 0 {
  24.         err := c.updateAppliedCondition(ctx, work, metav1.ConditionFalse, "AppliedFailed", ...)
  25.         return errors.NewAggregate(errs)
  26.     }
  27.    
  28.     err := c.updateAppliedCondition(ctx, work, metav1.ConditionTrue, "AppliedSuccessful", "Manifest has been successfully applied")
  29.     return nil
  30. }
复制代码
4.2.4 tryCreateOrUpdateWorkload 函数详解
  1. func (c *Controller) tryCreateOrUpdateWorkload(ctx context.Context, clusterName string, workload *unstructured.Unstructured) error {
  2.     fedKey, err := keys.FederatedKeyFunc(clusterName, workload)
  3.    
  4.     // 1. 检查资源是否已存在
  5.     clusterObj, err := helper.GetObjectFromCache(c.RESTMapper, c.InformerManager, fedKey)
  6.    
  7.     if err != nil {
  8.         if !apierrors.IsNotFound(err) {
  9.             return err
  10.         }
  11.         // 2. 资源不存在,创建
  12.         err = c.ObjectWatcher.Create(ctx, clusterName, workload)
  13.         metrics.CountCreateResourceToCluster(err, workload.GetAPIVersion(), workload.GetKind(), clusterName, false)
  14.         return err
  15.     }
  16.    
  17.     // 3. 资源存在,更新
  18.     operationResult, err := c.ObjectWatcher.Update(ctx, clusterName, workload, clusterObj)
  19.     metrics.CountUpdateResourceToCluster(err, workload.GetAPIVersion(), workload.GetKind(), clusterName, string(operationResult))
  20.     return err
  21. }
复制代码
关键利用

  • 反序列化 Manifest:将 JSON 反序列化为 Unstructured 对象
  • 查抄资源存在性:通过 Informer 缓存查抄资源是否已存在
  • 创建或更新:使用 ObjectWatcher 创建或更新资源
  • 更新 Condition:根据结果更新 Work 的 Applied Condition
4.3 Work Status Controller 状态同步

4.3.1 Reconcile 流程

位置:pkg/controllers/status/work_status_controller.go
  1. func (c *WorkStatusController) Reconcile(ctx context.Context, req controllerruntime.Request) (controllerruntime.Result, error) {
  2.     // 1. 获取 Work
  3.     work := &workv1alpha1.Work{}
  4.     if err := c.Client.Get(ctx, req.NamespacedName, work); err != nil {
  5.         return controllerruntime.Result{}, err
  6.     }
  7.    
  8.     // 2. 检查资源是否已应用
  9.     if !helper.IsResourceApplied(&work.Status) {
  10.         return controllerruntime.Result{}, nil
  11.     }
  12.    
  13.     // 3. 获取集群名称
  14.     clusterName, err := names.GetClusterName(work.GetNamespace())
  15.    
  16.     // 4. 获取 Cluster 对象
  17.     cluster, err := util.GetCluster(c.Client, clusterName)
  18.    
  19.     // 5. 检查集群是否就绪
  20.     if !util.IsClusterReady(&cluster.Status) {
  21.         return controllerruntime.Result{}, fmt.Errorf("cluster(%s) not ready", cluster.Name)
  22.     }
  23.    
  24.     // 6. 构建资源 Informer
  25.     return c.buildResourceInformers(cluster, work)
  26. }
复制代码
4.3.2 动态 Informer 机制
  1. func (c *WorkStatusController) buildResourceInformers(cluster *clusterv1alpha1.Cluster, work *workv1alpha1.Work) (controllerruntime.Result, error) {
  2.     // 为 Work 中的每个 Manifest 注册 Informer
  3.     err := c.registerInformersAndStart(cluster, work)
  4.     return controllerruntime.Result{}, nil
  5. }
复制代码
工作原理

  • 动态注册 Informer:为 Work 中的每个资源范例注册 Informer
  • 监听资源变革:Informer 监听成员集群中的资源变革
  • 事故处理惩罚:资源变革时触发 onAdd、onUpdate、onDelete 回调
  • 状态同步:将资源状态同步到 Work 的 status.manifestStatuses
4.3.3 状态同步逻辑
  1. func (c *WorkStatusController) syncWorkStatus(key util.QueueKey) error {
  2.     fedKey, ok := key.(keys.FederatedKey)
  3.    
  4.     // 1. 从缓存获取资源
  5.     observedObj, err := helper.GetObjectFromCache(c.RESTMapper, c.InformerManager, fedKey)
  6.    
  7.     // 2. 获取对应的 Work
  8.     work, err := c.getWorkByResource(fedKey)
  9.    
  10.     // 3. 更新 Work 状态
  11.     err = c.updateWorkStatus(work, observedObj, fedKey)
  12.    
  13.     return nil
  14. }
复制代码
状态更新

  • 获取资源状态:从 Informer 缓存获取资源的最新状态
  • 盘算康健状态:通过 Resource Interpreter 盘算资源康健状态
  • 更新 ManifestStatus:更新 Work 的 status.manifestStatuses
  • 更新 Condition:更新 Work 的 Condition(Available、Degraded 等)
4.4 Work 删除处理惩罚

4.4.1 handleWorkDelete 函数
  1. func (c *Controller) handleWorkDelete(ctx context.Context, work *workv1alpha1.Work, cluster *clusterv1alpha1.Cluster) error {
  2.     // 1. 检查是否保留资源
  3.     if ptr.Deref(work.Spec.PreserveResourcesOnDeletion, false) {
  4.         if err := c.cleanupPolicyClaimMetadata(ctx, work, cluster); err != nil {
  5.             return err
  6.         }
  7.         klog.V(4).InfoS("Preserving resource on deletion from work on cluster", ...)
  8.         return nil
  9.     }
  10.    
  11.     // 2. 检查集群是否就绪
  12.     if util.IsClusterReady(&cluster.Status) {
  13.         err := c.tryDeleteWorkload(ctx, cluster.Name, work)
  14.         return err
  15.     } else if cluster.DeletionTimestamp.IsZero() {
  16.         return fmt.Errorf("cluster(%s) not ready", cluster.Name)
  17.     }
  18.    
  19.     return nil
  20. }
复制代码
删除逻辑

  • 查抄 PreserveResourcesOnDeletion:如果为 true,只清算元数据,不删除资源
  • 查抄集群状态:只有在集群停当时才删除资源
  • 删除资源:遍历 Work 的 Manifest,删除成员集群中的资源
4.5 计划模式总结

4.5.1 Finalizer 机制

Work 使用 Finalizer 确保删除时的资源清算:
  1. Finalizers: []string{util.ExecutionControllerFinalizer}
复制代码
作用

  • 防止 Work 被不测删除
  • 确保删除前完成资源清算
  • 支持优雅删除
4.5.2 ExecutionSpace 隔离

每个成员集群对应一个 ExecutionSpace 定名空间:
  1. workNamespace := names.GenerateExecutionSpaceName(targetCluster.Name)
  2. // 结果:karmada-es-{cluster-name}
复制代码
上风

  • 集群级别的资源隔离
  • 便于权限管理(RBAC)
  • 简化资源查询
4.5.3 动态 Informer 注册

Work Status Controller 动态为每个 Work 注册 Informer:
上风

  • 按需创建 Informer,节省资源
  • 支持恣意资源范例
  • 自动清算不再须要的 Informer
4.5.4 幂等性包管

使用 CreateOrUpdate 确保 Work 创建的幂等性:
  1. operationResult, err = controllerutil.CreateOrUpdate(ctx, c, runtimeObject, func() error {
  2.     runtimeObject.Spec = work.Spec
  3.     return nil
  4. })
复制代码
上风

  • 支持重复创建
  • 自动更新已存在的 Work
  • 镌汰辩说
五、总结

5.1 Work 的焦点代价


  • 资源分发载体:将 ResourceBinding 的实验结果转换为可实验的工作负载
  • 集群隔离:通过 ExecutionSpace 实现集群级别的资源隔离
  • 状态网络:网络成员集群中资源的实际状态,反馈到控制平面
  • 实验控制:支持停息、保存等控制本领
5.2 关键概念

概念阐明ExecutionSpace每个成员集群对应的定名空间,用于存储 WorkManifestWork 中存储的资源清单(JSON 格式)ConditionWork 的状态条件(Applied、Available、Degraded 等)ManifestStatus每个 Manifest 的具体状态SuspendDispatching停息分发,但不删除已存在的资源PreserveResourcesOnDeletion删除 Work 时保存成员集群中的资源5.3 与其他组件的关系
  1. ResourceBinding
  2.     ↓ (Binding Controller)
  3. Work (每个集群一个)
  4.     ↓ (Execution Controller)
  5. 成员集群中的实际资源
  6.     ↑ (Work Status Controller)
  7. Work.Status (状态反馈)
复制代码
5.4 完备工作流程


  • 创建阶段

    • Binding Controller 根据 ResourceBinding 创建 Work
    • 为每个目标集群创建一个 Work
    • Work 存储在对应的 ExecutionSpace 中

  • 实验阶段

    • Execution Controller 监听 Work 变革
    • 将 Work 中的 Manifest 应用到成员集群
    • 更新 Work 的 Applied Condition

  • 状态同步阶段

    • Work Status Controller 为 Work 注册 Informer
    • 监听成员集群中的资源变革
    • 同步资源状态到 Work.Status

  • 删除阶段

    • Execution Controller 处理惩罚 Work 删除
    • 根据 PreserveResourcesOnDeletion 决定是否删除资源
    • 移除 Finalizer,完成删除

参考资源


  • Work API 界说:pkg/apis/work/v1alpha1/work_types.go
  • Binding Controller:pkg/controllers/binding/binding_controller.go
  • Execution Controller:pkg/controllers/execution/execution_controller.go
  • Work Status Controller:pkg/controllers/status/work_status_controller.go
  • 官方文档:https://karmada.io/docs/

免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金.
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表