Karmada-Work 组件详解

Karmada Work 组件详解

目录


一、使用背景

1.1 为什么需要 Work 资源?

Work 是 Karmada 资源传播链路中的执行载体,它是 ResourceBinding 的下游,负责将资源模板实际分发到成员集群。

核心作用

  1. 资源分发载体:承载要分发到成员集群的资源清单(Manifests)
  2. 集群隔离:每个 Work 对象对应一个目标集群,实现集群级别的资源隔离
  3. 状态收集:记录资源在成员集群中的实际状态(Applied、Progressing、Available、Degraded)
  4. 执行控制:支持暂停分发(SuspendDispatching)、保留资源(PreserveResourcesOnDeletion)等控制能力

1.2 在资源传播链路中的位置

资源模板 (Deployment)
    ↓
PropagationPolicy (传播策略)
    ↓
ResourceBinding (RB) - 绑定关系
    ↓
Work (每个目标集群一个) ⭐
    ↓
成员集群中的实际资源 (Deployment)

关键关系

  • 1 个 ResourceBindingN 个 Work(N = 目标集群数量)
  • 1 个 Work1 个成员集群
  • 1 个 Work1 个或多个资源清单(Manifests)

1.3 Work 的命名空间隔离机制

Work 对象存储在 ExecutionSpace 命名空间中,每个成员集群对应一个 ExecutionSpace:

karmada-es-member1/  ← 成员集群 member1 的 Work
    ├── work-deployment-nginx
    └── work-service-nginx

karmada-es-member2/  ← 成员集群 member2 的 Work
    ├── work-deployment-nginx
    └── work-service-nginx

命名规则karmada-es-{cluster-name}


二、Work API 定义

2.1 基本结构

Work 是一个命名空间级(NamespaceScoped)的 CRD 资源,定义在 pkg/apis/work/v1alpha1/work_types.go

// Work defines a list of resources to be deployed on the member cluster.
type Work struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    // Spec represents the desired behavior of Work.
    Spec WorkSpec `json:"spec"`

    // Status represents the status of PropagationStatus.
    Status WorkStatus `json:"status,omitempty"`
}

2.2 WorkSpec - 期望状态

type WorkSpec struct {
    // Workload represents the manifest workload to be deployed on managed cluster.
    Workload WorkloadTemplate `json:"workload,omitempty"`

    // SuspendDispatching controls whether dispatching should be suspended.
    // true means stop propagating to the corresponding member cluster.
    SuspendDispatching *bool `json:"suspendDispatching,omitempty"`

    // PreserveResourcesOnDeletion controls whether resources should be preserved
    // on the member cluster when the Work object is deleted.
    PreserveResourcesOnDeletion *bool `json:"preserveResourcesOnDeletion,omitempty"`
}

核心字段说明

字段 类型 说明
Workload WorkloadTemplate 要部署的资源清单列表
SuspendDispatching *bool 是否暂停分发(true 时 Execution Controller 不会应用资源)
PreserveResourcesOnDeletion *bool Work 删除时是否保留成员集群中的资源

2.3 WorkloadTemplate - 资源清单模板

type WorkloadTemplate struct {
    // Manifests represents a list of Kubernetes resources to be deployed.
    Manifests []Manifest `json:"manifests,omitempty"`
}

type Manifest struct {
    runtime.RawExtension `json:",inline"`  // 任意 Kubernetes 资源的 JSON
}

Manifest 内容:可以是任何 Kubernetes 资源(Deployment、Service、ConfigMap 等)的 JSON 序列化。

2.4 WorkStatus - 实际状态

type WorkStatus struct {
    // Conditions contain the different condition statuses for this work.
    Conditions []metav1.Condition `json:"conditions,omitempty"`

    // ManifestStatuses contains running status of manifests in spec.
    ManifestStatuses []ManifestStatus `json:"manifestStatuses,omitempty"`
}

Condition 类型

Condition 类型 说明
Applied 资源是否已成功应用到成员集群
Progressing 资源是否正在应用过程中
Available 资源是否在成员集群中存在
Degraded 资源状态是否异常
Dispatching 分发是否被暂停

ManifestStatus:记录每个 Manifest 的详细状态:

type ManifestStatus struct {
    Identifier ResourceIdentifier `json:"identifier"`  // 资源标识
    Status     *runtime.RawExtension `json:"status,omitempty"`  // 资源状态
    Health     ResourceHealth `json:"health,omitempty"`  // 健康状态
}

2.5 完整示例

apiVersion: work.karmada.io/v1alpha1
kind: Work
metadata:
  name: work-deployment-nginx
  namespace: karmada-es-member1
  labels:
    resourcebinding.karmada.io/name: deployment-nginx
    resourcebinding.karmada.io/namespace: default
  finalizers:
    - execution.karmada.io/execution-controller
spec:
  workload:
    manifests:
    - apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx
        namespace: default
        labels:
          app: nginx
          resource.karmada.io/managed-by: karmada
        annotations:
          work.karmada.io/name: work-deployment-nginx
          work.karmada.io/namespace: karmada-es-member1
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx:1.21
status:
  conditions:
  - type: Applied
    status: "True"
    reason: AppliedSuccessful
    message: Manifest has been successfully applied
  - type: Available
    status: "True"
    reason: Available
    message: All resources of the Work exists on the managed cluster
  manifestStatuses:
  - identifier:
      ordinal: 0
      group: apps
      version: v1
      kind: Deployment
      resource: deployments
      namespace: default
      name: nginx
    health: Healthy
    status:
      replicas: 3
      readyReplicas: 3
      availableReplicas: 3

三、使用方式

3.1 Work 的创建方式

Work 通常由 Binding Controller 自动创建,用户不需要手动创建。但了解其创建过程有助于理解系统:

自动创建流程

  1. 用户创建资源模板
kubectl create deployment nginx --image=nginx:1.21
  1. 用户创建 PropagationPolicy
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
  1. Detector 创建 ResourceBinding

  2. Scheduler 为 ResourceBinding 选择集群

  3. Binding Controller 创建 Work(每个目标集群一个)

手动查看 Work

# 查看所有 Work
kubectl get work -A

# 查看特定集群的 Work
kubectl get work -n karmada-es-member1

# 查看 Work 详情
kubectl get work work-deployment-nginx -n karmada-es-member1 -o yaml

# 查看 Work 状态
kubectl describe work work-deployment-nginx -n karmada-es-member1

3.2 控制 Work 的行为

暂停分发(SuspendDispatching)

通过设置 spec.suspendDispatching: true,可以暂停 Work 的分发:

apiVersion: work.karmada.io/v1alpha1
kind: Work
metadata:
  name: work-deployment-nginx
  namespace: karmada-es-member1
spec:
  suspendDispatching: true  # 暂停分发
  workload:
    manifests:
    - ...

效果

  • Execution Controller 不会应用资源到成员集群
  • 已存在的资源不会被删除
  • 状态收集仍然继续

保留资源(PreserveResourcesOnDeletion)

通过设置 spec.preserveResourcesOnDeletion: true,可以在删除 Work 时保留成员集群中的资源:

apiVersion: work.karmada.io/v1alpha1
kind: Work
metadata:
  name: work-deployment-nginx
  namespace: karmada-es-member1
spec:
  preserveResourcesOnDeletion: true  # 删除 Work 时保留资源
  workload:
    manifests:
    - ...

效果

  • 删除 Work 时,成员集群中的资源不会被删除
  • 适用于需要手动管理资源的场景

3.3 监控 Work 状态

查看 Work 状态

# 查看 Work 的 Condition
kubectl get work work-deployment-nginx -n karmada-es-member1 \
  -o jsonpath='{.status.conditions[*].type}:{.status.conditions[*].status}'

# 查看 Work 的 Manifest 状态
kubectl get work work-deployment-nginx -n karmada-es-member1 \
  -o jsonpath='{.status.manifestStatuses[*].health}'

常见状态

状态 说明 处理方式
Applied=True 资源已成功应用 正常
Applied=False 资源应用失败 检查 Execution Controller 日志
Available=True 资源在集群中存在 正常
Available=False 资源在集群中不存在 检查成员集群状态
Degraded=True 资源状态异常 检查资源健康状态

3.4 故障排查

Work 未应用

# 1. 检查 Work 是否存在
kubectl get work -n karmada-es-member1

# 2. 检查 Work 的 SuspendDispatching
kubectl get work work-deployment-nginx -n karmada-es-member1 \
  -o jsonpath='{.spec.suspendDispatching}'

# 3. 检查 Execution Controller 日志
kubectl logs -n karmada-system deployment/karmada-controller-manager \
  -c karmada-controller-manager | grep execution

# 4. 检查成员集群连接
kubectl get cluster member1 -o yaml

Work 状态未同步

# 1. 检查 Work Status Controller 日志
kubectl logs -n karmada-system deployment/karmada-controller-manager \
  -c karmada-controller-manager | grep work-status

# 2. 检查成员集群中的资源是否存在
kubectl --context member1 get deployment nginx

# 3. 检查 Work 的 Manifest 内容
kubectl get work work-deployment-nginx -n karmada-es-member1 \
  -o jsonpath='{.spec.workload.manifests[0]}' | jq

四、源码原理

4.1 Work 的创建流程

4.1.1 Binding Controller 创建 Work

位置pkg/controllers/binding/binding_controller.go

// syncBinding will sync resourceBinding to Works.
func (c *ResourceBindingController) syncBinding(ctx context.Context, binding *workv1alpha2.ResourceBinding) (controllerruntime.Result, error) {
    // 1. 获取资源模板
    workload, err := helper.FetchResourceTemplate(ctx, c.DynamicClient, c.InformerManager, c.RESTMapper, binding.Spec.Resource)
    
    // 2. 为每个目标集群创建 Work
    err = ensureWork(ctx, c.Client, c.ResourceInterpreter, workload, c.OverrideManager, binding, apiextensionsv1.NamespaceScoped)
    
    return controllerruntime.Result{}, err
}

4.1.2 ensureWork 函数详解

位置pkg/controllers/binding/common.go

func ensureWork(
    ctx context.Context, 
    c client.Client, 
    resourceInterpreter resourceinterpreter.ResourceInterpreter,
    workload *unstructured.Unstructured,
    overrideManager overridemanager.OverrideManager, 
    binding metav1.Object, 
    scope apiextensionsv1.ResourceScope,
) error {
    bindingSpec := getBindingSpec(binding, scope)
    targetClusters := mergeTargetClusters(bindingSpec.Clusters, bindingSpec.RequiredBy)
    
    // 为每个目标集群创建 Work
    for i := range targetClusters {
        targetCluster := targetClusters[i]
        clonedWorkload := workload.DeepCopy()
        
        // 1. 确定 Work 的命名空间(ExecutionSpace)
        workNamespace := names.GenerateExecutionSpaceName(targetCluster.Name)
        
        // 2. 调整副本数(如果适用)
        if bindingSpec.IsWorkload() {
            if resourceInterpreter.HookEnabled(clonedWorkload.GroupVersionKind(), configv1alpha1.InterpreterOperationReviseReplica) {
                clonedWorkload, err = resourceInterpreter.ReviseReplica(clonedWorkload, int64(targetCluster.Replicas))
            }
        }
        
        // 3. 应用 OverridePolicy
        cops, ops, err := overrideManager.ApplyOverridePolicies(clonedWorkload, targetCluster.Name)
        
        // 4. 构建 Work 元数据
        workMeta := metav1.ObjectMeta{
            Name:        names.GenerateWorkName(clonedWorkload.GetKind(), clonedWorkload.GetName(), clonedWorkload.GetNamespace()),
            Namespace:   workNamespace,
            Finalizers:  []string{util.ExecutionControllerFinalizer},
            Labels:      workLabel,
            Annotations: annotations,
        }
        
        // 5. 创建或更新 Work
        err = ctrlutil.CreateOrUpdateWork(ctx, c, workMeta, clonedWorkload, ...)
    }
    
    return errors.NewAggregate(errs)
}

关键步骤

  1. 遍历目标集群:为 ResourceBinding 中的每个目标集群创建一个 Work
  2. 克隆资源模板:为每个集群创建独立的资源副本
  3. 调整副本数:根据调度结果调整副本数(Divided 模式)
  4. 应用 OverridePolicy:应用集群特定的配置覆盖
  5. 创建 Work:调用 CreateOrUpdateWork 创建或更新 Work

4.1.3 CreateOrUpdateWork 函数详解

位置pkg/controllers/ctrlutil/work.go

func CreateOrUpdateWork(ctx context.Context, c client.Client, workMeta metav1.ObjectMeta, resource *unstructured.Unstructured, options ...WorkOption) error {
    resource = resource.DeepCopy()
    
    // 1. 设置标签和注解
    util.MergeLabel(resource, util.ManagedByKarmadaLabel, util.ManagedByKarmadaLabelValue)
    util.MergeAnnotation(resource, workv1alpha2.ResourceTemplateUIDAnnotation, string(resource.GetUID()))
    util.MergeAnnotation(resource, workv1alpha2.WorkNameAnnotation, workMeta.Name)
    util.MergeAnnotation(resource, workv1alpha2.WorkNamespaceAnnotation, workMeta.Namespace)
    
    // 2. 清理无关字段
    err := prune.RemoveIrrelevantFields(resource, prune.RemoveJobTTLSeconds)
    
    // 3. 构建 Work 对象
    work := &workv1alpha1.Work{
        ObjectMeta: workMeta,
    }
    applyWorkOptions(work, options)
    
    // 4. 序列化资源为 JSON
    workloadJSON, err := json.Marshal(resource)
    
    // 5. 创建或更新 Work
    err = retry.RetryOnConflict(retry.DefaultRetry, func() (err error) {
        operationResult, err = controllerutil.CreateOrUpdate(ctx, c, runtimeObject, func() error {
            runtimeObject.Spec.Workload = workv1alpha1.WorkloadTemplate{
                Manifests: []workv1alpha1.Manifest{
                    {
                        RawExtension: runtime.RawExtension{
                            Raw: workloadJSON,
                        },
                    },
                },
            }
            return nil
        })
        return err
    })
    
    return nil
}

关键操作

  1. 标记资源:为资源添加 Karmada 管理标签和注解
  2. 清理字段:移除不需要同步的字段(如 statusmetadata.uid 等)
  3. 序列化:将资源序列化为 JSON,存储在 spec.workload.manifests
  4. 幂等更新:使用 CreateOrUpdate 确保幂等性

4.2 Execution Controller 执行 Work

4.2.1 Reconcile 流程

位置pkg/controllers/execution/execution_controller.go

func (c *Controller) Reconcile(ctx context.Context, req controllerruntime.Request) (controllerruntime.Result, error) {
    // 1. 获取 Work
    work := &workv1alpha1.Work{}
    if err := c.Client.Get(ctx, req.NamespacedName, work); err != nil {
        return controllerruntime.Result{}, err
    }
    
    // 2. 获取集群名称
    clusterName, err := names.GetClusterName(work.Namespace)
    
    // 3. 获取 Cluster 对象
    cluster, err := util.GetCluster(c.Client, clusterName)
    
    // 4. 处理删除
    if !work.DeletionTimestamp.IsZero() {
        if err := c.handleWorkDelete(ctx, work, cluster); err != nil {
            return controllerruntime.Result{}, err
        }
        return c.removeFinalizer(ctx, work)
    }
    
    // 5. 检查是否暂停分发
    if util.IsWorkSuspendDispatching(work) {
        return controllerruntime.Result{}, nil
    }
    
    // 6. 检查集群是否就绪
    if !util.IsClusterReady(&cluster.Status) {
        return controllerruntime.Result{}, fmt.Errorf("cluster(%s) not ready", cluster.Name)
    }
    
    // 7. 同步 Work 到集群
    return c.syncWork(ctx, clusterName, work)
}

4.2.2 syncWork 函数详解

func (c *Controller) syncWork(ctx context.Context, clusterName string, work *workv1alpha1.Work) (controllerruntime.Result, error) {
    start := time.Now()
    err := c.syncToClusters(ctx, clusterName, work)
    metrics.ObserveSyncWorkloadLatency(err, start)
    
    if err != nil {
        msg := fmt.Sprintf("Failed to sync work(%s/%s) to cluster(%s), err: %v", work.Namespace, work.Name, clusterName, err)
        c.EventRecorder.Event(work, corev1.EventTypeWarning, events.EventReasonSyncWorkloadFailed, msg)
        return controllerruntime.Result{}, err
    }
    
    msg := fmt.Sprintf("Sync work(%s/%s) to cluster(%s) successful.", work.Namespace, work.Name, clusterName)
    c.EventRecorder.Event(work, corev1.EventTypeNormal, events.EventReasonSyncWorkloadSucceed, msg)
    return controllerruntime.Result{}, nil
}

4.2.3 syncToClusters 函数详解

func (c *Controller) syncToClusters(ctx context.Context, clusterName string, work *workv1alpha1.Work) error {
    var errs []error
    syncSucceedNum := 0
    
    // 遍历 Work 中的所有 Manifest
    for _, manifest := range work.Spec.Workload.Manifests {
        workload := &unstructured.Unstructured{}
        err := workload.UnmarshalJSON(manifest.Raw)
        if err != nil {
            errs = append(errs, err)
            continue
        }
        
        // 创建或更新资源
        if err = c.tryCreateOrUpdateWorkload(ctx, clusterName, workload); err != nil {
            errs = append(errs, err)
            continue
        }
        syncSucceedNum++
    }
    
    // 更新 Applied Condition
    if len(errs) > 0 {
        err := c.updateAppliedCondition(ctx, work, metav1.ConditionFalse, "AppliedFailed", ...)
        return errors.NewAggregate(errs)
    }
    
    err := c.updateAppliedCondition(ctx, work, metav1.ConditionTrue, "AppliedSuccessful", "Manifest has been successfully applied")
    return nil
}

4.2.4 tryCreateOrUpdateWorkload 函数详解

func (c *Controller) tryCreateOrUpdateWorkload(ctx context.Context, clusterName string, workload *unstructured.Unstructured) error {
    fedKey, err := keys.FederatedKeyFunc(clusterName, workload)
    
    // 1. 检查资源是否已存在
    clusterObj, err := helper.GetObjectFromCache(c.RESTMapper, c.InformerManager, fedKey)
    
    if err != nil {
        if !apierrors.IsNotFound(err) {
            return err
        }
        // 2. 资源不存在,创建
        err = c.ObjectWatcher.Create(ctx, clusterName, workload)
        metrics.CountCreateResourceToCluster(err, workload.GetAPIVersion(), workload.GetKind(), clusterName, false)
        return err
    }
    
    // 3. 资源存在,更新
    operationResult, err := c.ObjectWatcher.Update(ctx, clusterName, workload, clusterObj)
    metrics.CountUpdateResourceToCluster(err, workload.GetAPIVersion(), workload.GetKind(), clusterName, string(operationResult))
    return err
}

关键操作

  1. 反序列化 Manifest:将 JSON 反序列化为 Unstructured 对象
  2. 检查资源存在性:通过 Informer 缓存检查资源是否已存在
  3. 创建或更新:使用 ObjectWatcher 创建或更新资源
  4. 更新 Condition:根据结果更新 Work 的 Applied Condition

4.3 Work Status Controller 状态同步

4.3.1 Reconcile 流程

位置pkg/controllers/status/work_status_controller.go

func (c *WorkStatusController) Reconcile(ctx context.Context, req controllerruntime.Request) (controllerruntime.Result, error) {
    // 1. 获取 Work
    work := &workv1alpha1.Work{}
    if err := c.Client.Get(ctx, req.NamespacedName, work); err != nil {
        return controllerruntime.Result{}, err
    }
    
    // 2. 检查资源是否已应用
    if !helper.IsResourceApplied(&work.Status) {
        return controllerruntime.Result{}, nil
    }
    
    // 3. 获取集群名称
    clusterName, err := names.GetClusterName(work.GetNamespace())
    
    // 4. 获取 Cluster 对象
    cluster, err := util.GetCluster(c.Client, clusterName)
    
    // 5. 检查集群是否就绪
    if !util.IsClusterReady(&cluster.Status) {
        return controllerruntime.Result{}, fmt.Errorf("cluster(%s) not ready", cluster.Name)
    }
    
    // 6. 构建资源 Informer
    return c.buildResourceInformers(cluster, work)
}

4.3.2 动态 Informer 机制

func (c *WorkStatusController) buildResourceInformers(cluster *clusterv1alpha1.Cluster, work *workv1alpha1.Work) (controllerruntime.Result, error) {
    // 为 Work 中的每个 Manifest 注册 Informer
    err := c.registerInformersAndStart(cluster, work)
    return controllerruntime.Result{}, nil
}

工作原理

  1. 动态注册 Informer:为 Work 中的每个资源类型注册 Informer
  2. 监听资源变化:Informer 监听成员集群中的资源变化
  3. 事件处理:资源变化时触发 onAddonUpdateonDelete 回调
  4. 状态同步:将资源状态同步到 Work 的 status.manifestStatuses

4.3.3 状态同步逻辑

func (c *WorkStatusController) syncWorkStatus(key util.QueueKey) error {
    fedKey, ok := key.(keys.FederatedKey)
    
    // 1. 从缓存获取资源
    observedObj, err := helper.GetObjectFromCache(c.RESTMapper, c.InformerManager, fedKey)
    
    // 2. 获取对应的 Work
    work, err := c.getWorkByResource(fedKey)
    
    // 3. 更新 Work 状态
    err = c.updateWorkStatus(work, observedObj, fedKey)
    
    return nil
}

状态更新

  1. 获取资源状态:从 Informer 缓存获取资源的最新状态
  2. 计算健康状态:通过 Resource Interpreter 计算资源健康状态
  3. 更新 ManifestStatus:更新 Work 的 status.manifestStatuses
  4. 更新 Condition:更新 Work 的 Condition(Available、Degraded 等)

4.4 Work 删除处理

4.4.1 handleWorkDelete 函数

func (c *Controller) handleWorkDelete(ctx context.Context, work *workv1alpha1.Work, cluster *clusterv1alpha1.Cluster) error {
    // 1. 检查是否保留资源
    if ptr.Deref(work.Spec.PreserveResourcesOnDeletion, false) {
        if err := c.cleanupPolicyClaimMetadata(ctx, work, cluster); err != nil {
            return err
        }
        klog.V(4).InfoS("Preserving resource on deletion from work on cluster", ...)
        return nil
    }
    
    // 2. 检查集群是否就绪
    if util.IsClusterReady(&cluster.Status) {
        err := c.tryDeleteWorkload(ctx, cluster.Name, work)
        return err
    } else if cluster.DeletionTimestamp.IsZero() {
        return fmt.Errorf("cluster(%s) not ready", cluster.Name)
    }
    
    return nil
}

删除逻辑

  1. 检查 PreserveResourcesOnDeletion:如果为 true,只清理元数据,不删除资源
  2. 检查集群状态:只有在集群就绪时才删除资源
  3. 删除资源:遍历 Work 的 Manifest,删除成员集群中的资源

4.5 设计模式总结

4.5.1 Finalizer 机制

Work 使用 Finalizer 确保删除时的资源清理:

Finalizers: []string{util.ExecutionControllerFinalizer}

作用

  • 防止 Work 被意外删除
  • 确保删除前完成资源清理
  • 支持优雅删除

4.5.2 ExecutionSpace 隔离

每个成员集群对应一个 ExecutionSpace 命名空间:

workNamespace := names.GenerateExecutionSpaceName(targetCluster.Name)
// 结果:karmada-es-{cluster-name}

优势

  • 集群级别的资源隔离
  • 便于权限管理(RBAC)
  • 简化资源查询

4.5.3 动态 Informer 注册

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

优势

  • 按需创建 Informer,节省资源
  • 支持任意资源类型
  • 自动清理不再需要的 Informer

4.5.4 幂等性保证

使用 CreateOrUpdate 确保 Work 创建的幂等性:

operationResult, err = controllerutil.CreateOrUpdate(ctx, c, runtimeObject, func() error {
    runtimeObject.Spec = work.Spec
    return nil
})

优势

  • 支持重复创建
  • 自动更新已存在的 Work
  • 减少冲突

五、总结

5.1 Work 的核心价值

  1. 资源分发载体:将 ResourceBinding 的执行结果转换为可执行的工作负载
  2. 集群隔离:通过 ExecutionSpace 实现集群级别的资源隔离
  3. 状态收集:收集成员集群中资源的实际状态,反馈到控制平面
  4. 执行控制:支持暂停、保留等控制能力

5.2 关键概念

概念 说明
ExecutionSpace 每个成员集群对应的命名空间,用于存储 Work
Manifest Work 中存储的资源清单(JSON 格式)
Condition Work 的状态条件(Applied、Available、Degraded 等)
ManifestStatus 每个 Manifest 的详细状态
SuspendDispatching 暂停分发,但不删除已存在的资源
PreserveResourcesOnDeletion 删除 Work 时保留成员集群中的资源

5.3 与其他组件的关系

ResourceBinding
    ↓ (Binding Controller)
Work (每个集群一个)
    ↓ (Execution Controller)
成员集群中的实际资源
    ↑ (Work Status Controller)
Work.Status (状态反馈)

5.4 完整工作流程

  1. 创建阶段

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

    • Execution Controller 监听 Work 变化
    • 将 Work 中的 Manifest 应用到成员集群
    • 更新 Work 的 Applied Condition
  3. 状态同步阶段

    • Work Status Controller 为 Work 注册 Informer
    • 监听成员集群中的资源变化
    • 同步资源状态到 Work.Status
  4. 删除阶段

    • 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/
posted @ 2026-01-14 23:06  Mephostopheles  阅读(0)  评论(0)    收藏  举报