找回密码
 立即注册
首页 业界区 安全 Karmada-Cluster 组件详解

Karmada-Cluster 组件详解

巨耗 2026-1-13 15:50:00
Karmada Cluster 组件详解

目录


  • 一、使用背景
  • 二、Cluster API 定义
  • 三、使用方式
  • 四、源码原理
  • 五、总结
一、使用背景

1.1 为什么需要 Cluster 资源?

在 Karmada 多集群管理系统中,Cluster 是代表成员集群的核心资源对象。它的主要作用是:

  • 集群注册与发现:将 Kubernetes 集群注册到 Karmada 控制平面
  • 集群生命周期管理:管理集群的加入、健康检查、故障处理、删除等
  • 集群属性定义:记录集群的地理位置(Region/Zone)、云提供商、资源模型等信息
  • 调度决策依据:为 Scheduler 提供集群信息,用于资源分发决策
  • 状态同步:收集和展示成员集群的实时状态(节点、资源等)
1.2 在多集群架构中的位置
  1. Karmada 控制平面
  2.     │
  3.     ├── Cluster (成员集群1) ──┐
  4.     ├── Cluster (成员集群2) ──┼──> ResourceBinding ──> Work ──> 实际资源
  5.     └── Cluster (成员集群3) ──┘
复制代码
Cluster 是 Karmada 与成员集群之间的桥梁,所有资源分发都必须基于已注册的 Cluster。
二、Cluster API 定义

2.1 基本结构

Cluster 是一个集群级(ClusterScope)的 CRD 资源,定义在 pkg/apis/cluster/v1alpha1/types.go:
  1. // Cluster represents the desired state and status of a member cluster.
  2. type Cluster struct {
  3.     metav1.TypeMeta   `json:",inline"`
  4.     metav1.ObjectMeta `json:"metadata,omitempty"`
  5.    
  6.     // Spec 定义了集群的期望状态(配置信息)
  7.     Spec ClusterSpec `json:"spec"`
  8.    
  9.     // Status 表示集群的实际状态(运行时信息)
  10.     Status ClusterStatus `json:"status,omitempty"`
  11. }
复制代码
2.2 ClusterSpec - 期望配置

ClusterSpec 定义了集群的配置信息:
核心字段
  1. type ClusterSpec struct {
  2.     // ID: 集群唯一标识符
  3.     // 1. 优先从 ClusterProperty API 获取
  4.     // 2. 否则使用 kube-system namespace 的 UID
  5.     ID string `json:"id,omitempty"`
  6.    
  7.     // SyncMode: 同步模式(Push 或 Pull)
  8.     // - Push: 控制平面主动推送资源到成员集群
  9.     // - Pull: 成员集群的 Agent 主动拉取资源
  10.     SyncMode ClusterSyncMode `json:"syncMode"`
  11.    
  12.     // APIEndpoint: 成员集群的 API 地址
  13.     APIEndpoint string `json:"apiEndpoint,omitempty"`
  14.    
  15.     // SecretRef: 访问成员集群的凭证(包含 token 和 caBundle)
  16.     SecretRef *LocalSecretReference `json:"secretRef,omitempty"`
  17.    
  18.     // ImpersonatorSecretRef: Impersonator 的凭证(用于 Pull 模式)
  19.     ImpersonatorSecretRef *LocalSecretReference `json:"impersonatorSecretRef,omitempty"`
  20.    
  21.     // 连接配置
  22.     InsecureSkipTLSVerification bool   `json:"insecureSkipTLSVerification,omitempty"`
  23.     ProxyURL                    string `json:"proxyURL,omitempty"`
  24.     ProxyHeader                 map[string]string `json:"proxyHeader,omitempty"`
  25.    
  26.     // 集群属性(用于调度)
  27.     Provider string   `json:"provider,omitempty"`   // 云提供商(如 aws, alibaba)
  28.     Region   string   `json:"region,omitempty"`     // 区域
  29.     Zones    []string `json:"zones,omitempty"`      // 可用区列表
  30.    
  31.     // Taints: 集群污点(用于调度决策)
  32.     Taints []corev1.Taint `json:"taints,omitempty"`
  33.    
  34.     // ResourceModels: 资源模型(用于资源估算和调度)
  35.     ResourceModels []ResourceModel `json:"resourceModels,omitempty"`
  36. }
复制代码
SyncMode 详解
  1. const (
  2.     // Push 模式:控制平面主动推送
  3.     // - 控制器在控制平面运行,直接连接成员集群 API
  4.     // - 适合网络可达的场景
  5.     Push ClusterSyncMode = "Push"
  6.    
  7.     // Pull 模式:成员集群主动拉取
  8.     // - Agent 在成员集群运行,拉取控制平面的资源
  9.     // - 适合网络受限或安全隔离的场景
  10.     Pull ClusterSyncMode = "Pull"
  11. )
复制代码
2.3 ClusterStatus - 运行时状态

ClusterStatus 记录了集群的实时状态:
  1. type ClusterStatus struct {
  2.     // KubernetesVersion: Kubernetes 版本
  3.     KubernetesVersion string `json:"kubernetesVersion,omitempty"`
  4.    
  5.     // APIEnablements: 集群支持的 API 资源列表
  6.     APIEnablements []APIEnablement `json:"apiEnablements,omitempty"`
  7.    
  8.     // Conditions: 集群条件状态
  9.     Conditions []metav1.Condition `json:"conditions,omitempty"`
  10.    
  11.     // NodeSummary: 节点摘要
  12.     NodeSummary *NodeSummary `json:"nodeSummary,omitempty"`
  13.    
  14.     // ResourceSummary: 资源摘要(可分配、已分配、等待分配)
  15.     ResourceSummary *ResourceSummary `json:"resourceSummary,omitempty"`
  16.    
  17.     // RemedyActions: 需要执行的修复操作
  18.     RemedyActions []string `json:"remedyActions,omitempty"`
  19. }
复制代码
Conditions 类型
  1. const (
  2.     // ClusterConditionReady: 集群是否就绪
  3.     ClusterConditionReady = "Ready"
  4.    
  5.     // ClusterConditionCompleteAPIEnablements: API 启用是否完整
  6.     ClusterConditionCompleteAPIEnablements = "CompleteAPIEnablements"
  7. )
复制代码
ResourceSummary 结构
  1. type ResourceSummary struct {
  2.     // Allocatable: 可分配资源总量(所有节点的总和)
  3.     Allocatable corev1.ResourceList `json:"allocatable,omitempty"`
  4.    
  5.     // Allocating: 等待调度的资源(Pending Pods)
  6.     Allocating corev1.ResourceList `json:"allocating,omitempty"`
  7.    
  8.     // Allocated: 已分配的资源(已调度的 Pods)
  9.     Allocated corev1.ResourceList `json:"allocated,omitempty"`
  10.    
  11.     // AllocatableModelings: 资源模型统计
  12.     AllocatableModelings []AllocatableModeling `json:"allocatableModelings,omitempty"`
  13. }
复制代码
三、使用方式

3.1 注册集群(Push 模式)

使用 karmadactl join 命令注册集群:
  1. # 基本用法
  2. karmadactl join CLUSTER_NAME \
  3.   --cluster-kubeconfig=<成员集群的 kubeconfig> \
  4.   --kubeconfig=<Karmada 控制平面的 kubeconfig>
  5. # 完整示例
  6. karmadactl join member1 \
  7.   --cluster-kubeconfig=$HOME/.kube/member1.config \
  8.   --cluster-namespace=karmada-cluster \
  9.   --cluster-provider=aliyun \
  10.   --cluster-region=cn-hangzhou \
  11.   --cluster-zones=cn-hangzhou-a,cn-hangzhou-b \
  12.   --kubeconfig=$HOME/.kube/karmada.config
复制代码
工作原理

  • 读取成员集群的 kubeconfig
  • 提取集群 ID(优先从 ClusterProperty,否则使用 kube-system UID)
  • 创建访问凭证(Secret)
  • 在控制平面创建 Cluster 对象
  • Cluster Controller 检测到新集群,创建 ExecutionSpace(命名空间)
3.2 注册集群(Pull 模式)

Pull 模式需要成员集群主动注册:
  1. # Step 1: 在控制平面创建 bootstrap token
  2. karmadactl token create --print-register-command \
  3.   --kubeconfig=<Karmada 控制平面的 kubeconfig>
  4. # 输出示例:
  5. # karmadactl register 172.18.0.5:5443 \
  6. #   --token t8xfio.640u9gp9obc72v5d \
  7. #   --discovery-token-ca-cert-hash sha256:9cfa542ff48f43793d1816b1dd0a78ad574e349d8f6e005e6e32e8ab528e4244
  8. # Step 2: 在成员集群执行注册命令(指定成员集群的 kubeconfig)
  9. karmadactl register 172.18.0.5:5443 \
  10.   --token t8xfio.640u9gp9obc72v5d \
  11.   --discovery-token-ca-cert-hash sha256:9cfa542ff48f43793d1816b1dd0a78ad574e349d8f6e005e6e32e8ab528e4244 \
  12.   --kubeconfig=<成员集群的 kubeconfig>
复制代码
Pull 模式特点

  • 成员集群主动连接控制平面
  • 需要在成员集群部署 karmada-agent
  • 适合网络隔离场景
3.3 查看集群
  1. # 列出所有集群
  2. kubectl get clusters
  3. # 查看集群详细信息
  4. kubectl get cluster <cluster-name> -o yaml
  5. # 查看集群状态
  6. kubectl describe cluster <cluster-name>
复制代码
3.4 删除集群
  1. # 删除集群(会触发优雅删除流程)
  2. kubectl delete cluster <cluster-name>
复制代码
删除流程

  • 从所有 ResourceBinding 和 ClusterResourceBinding 中移除该集群
  • 删除该集群相关的所有 Work 对象
  • 删除 ExecutionSpace 命名空间
  • 删除 Cluster 对象
3.5 手动创建 Cluster(YAML)

也可以直接通过 YAML 创建:
  1. apiVersion: cluster.karmada.io/v1alpha1
  2. kind: Cluster
  3. metadata:
  4.   name: member1
  5. spec:
  6.   syncMode: Push
  7.   apiEndpoint: https://member1-api.example.com:6443
  8.   secretRef:
  9.     namespace: karmada-cluster
  10.     name: member1
  11.   provider: aliyun
  12.   region: cn-hangzhou
  13.   zones:
  14.     - cn-hangzhou-a
  15.     - cn-hangzhou-b
  16.   taints: []  # 可以添加污点来阻止调度
复制代码
四、源码原理

4.1 Cluster Controller 架构

Cluster Controller 负责管理 Cluster 资源的生命周期,代码位于 pkg/controllers/cluster/cluster_controller.go。
核心结构
  1. type Controller struct {
  2.     client.Client                    // Kubernetes 客户端
  3.     EventRecorder record.EventRecorder
  4.    
  5.     // 健康检查配置
  6.     ClusterMonitorPeriod      time.Duration  // 监控周期(默认 5s)
  7.     ClusterMonitorGracePeriod time.Duration  // 优雅期(默认 40s)
  8.     ClusterStartupGracePeriod time.Duration  // 启动优雅期(默认 1min)
  9.     CleanupCheckInterval      time.Duration  // 清理检查间隔(10s)
  10.    
  11.     // 集群健康状态缓存
  12.     clusterHealthMap *clusterHealthMap
  13.    
  14.     RateLimiterOptions ratelimiterflag.Options
  15. }
复制代码
4.2 核心工作流程

4.2.1 Reconcile 主流程
  1. func (c *Controller) Reconcile(ctx context.Context, req controllerruntime.Request) (controllerruntime.Result, error) {
  2.     // 1. 获取 Cluster 对象
  3.     cluster := &clusterv1alpha1.Cluster{}
  4.     if err := c.Client.Get(ctx, req.NamespacedName, cluster); err != nil {
  5.         if apierrors.IsNotFound(err) {
  6.             return controllerruntime.Result{}, nil
  7.         }
  8.         return controllerruntime.Result{}, err
  9.     }
  10.    
  11.     // 2. 判断是否为删除操作
  12.     if !cluster.DeletionTimestamp.IsZero() {
  13.         return c.removeCluster(ctx, cluster)
  14.     }
  15.    
  16.     // 3. 同步集群(创建/更新)
  17.     return c.syncCluster(ctx, cluster)
  18. }
复制代码
4.2.2 syncCluster - 集群同步
  1. func (c *Controller) syncCluster(ctx context.Context, cluster *clusterv1alpha1.Cluster) (controllerruntime.Result, error) {
  2.     // Step 1: 创建 ExecutionSpace(执行空间)
  3.     // ExecutionSpace 是一个命名空间,格式为: karmada-es-{cluster-name}
  4.     // 用于存放该集群相关的 Work 对象
  5.     err := c.createExecutionSpace(ctx, cluster)
  6.     if err != nil {
  7.         c.EventRecorder.Event(cluster, corev1.EventTypeWarning,
  8.             events.EventReasonCreateExecutionSpaceFailed, err.Error())
  9.         return controllerruntime.Result{}, err
  10.     }
  11.    
  12.     // Step 2: 根据集群条件添加污点
  13.     // - Ready=False: 添加 NotReady taint
  14.     // - Ready=Unknown: 添加 Unreachable taint
  15.     // - Ready=True: 移除所有调度相关的污点
  16.     err = c.taintClusterByCondition(ctx, cluster)
  17.     if err != nil {
  18.         return controllerruntime.Result{}, err
  19.     }
  20.    
  21.     // Step 3: 确保 Finalizer 存在
  22.     // Finalizer 用于在删除时执行清理逻辑
  23.     return c.ensureFinalizer(ctx, cluster)
  24. }
复制代码
关键点

  • ExecutionSpace:每个集群都有一个独立的命名空间,用于隔离该集群的 Work 对象
  • Taint 机制:根据集群健康状态自动添加污点,调度器会据此决策是否调度到该集群
4.2.3 createExecutionSpace - 创建执行空间
  1. func (c *Controller) createExecutionSpace(ctx context.Context, cluster *clusterv1alpha1.Cluster) error {
  2.     // 生成执行空间名称:karmada-es-{cluster-name}
  3.     executionSpaceName := names.GenerateExecutionSpaceName(cluster.Name)
  4.    
  5.     executionSpaceObj := &corev1.Namespace{}
  6.     err := c.Client.Get(ctx, types.NamespacedName{Name: executionSpaceName}, executionSpaceObj)
  7.     if err != nil {
  8.         if !apierrors.IsNotFound(err) {
  9.             return err
  10.         }
  11.         
  12.         // 创建新的执行空间
  13.         executionSpace := &corev1.Namespace{
  14.             ObjectMeta: metav1.ObjectMeta{
  15.                 Name: executionSpaceName,
  16.                 Labels: map[string]string{
  17.                     util.KarmadaSystemLabel: util.KarmadaSystemLabelValue,
  18.                 },
  19.             },
  20.         }
  21.         err = c.Client.Create(ctx, executionSpace)
  22.         if err != nil {
  23.             return err
  24.         }
  25.         klog.V(2).InfoS("Created execution space", "cluster", cluster.Name, "namespace", executionSpaceName)
  26.     }
  27.    
  28.     return nil
  29. }
复制代码
执行空间的作用

  • 隔离不同集群的 Work 对象
  • 便于管理和查询特定集群的工作负载
  • 支持 RBAC 权限隔离
4.2.4 taintClusterByCondition - 污点管理
  1. func (c *Controller) taintClusterByCondition(ctx context.Context, cluster *clusterv1alpha1.Cluster) error {
  2.     currentReadyCondition := meta.FindStatusCondition(cluster.Status.Conditions,
  3.         clusterv1alpha1.ClusterConditionReady)
  4.    
  5.     if currentReadyCondition != nil {
  6.         switch currentReadyCondition.Status {
  7.         case metav1.ConditionFalse:
  8.             // 集群不健康,添加 NotReady 污点
  9.             err = c.updateClusterTaints(ctx,
  10.                 []*corev1.Taint{NotReadyTaintTemplateForSched},
  11.                 []*corev1.Taint{UnreachableTaintTemplateForSched},
  12.                 cluster)
  13.         case metav1.ConditionUnknown:
  14.             // 集群不可达,添加 Unreachable 污点
  15.             err = c.updateClusterTaints(ctx,
  16.                 []*corev1.Taint{UnreachableTaintTemplateForSched},
  17.                 []*corev1.Taint{NotReadyTaintTemplateForSched},
  18.                 cluster)
  19.         case metav1.ConditionTrue:
  20.             // 集群健康,移除所有调度污点
  21.             err = c.updateClusterTaints(ctx,
  22.                 nil,
  23.                 []*corev1.Taint{NotReadyTaintTemplateForSched, UnreachableTaintTemplateForSched},
  24.                 cluster)
  25.         }
  26.     }
  27.     return err
  28. }
复制代码
污点定义
  1. var (
  2.     // UnreachableTaintTemplateForSched: 集群不可达时的污点
  3.     UnreachableTaintTemplateForSched = &corev1.Taint{
  4.         Key:    clusterv1alpha1.TaintClusterUnreachable,  // "cluster.karmada.io/unreachable"
  5.         Effect: corev1.TaintEffectNoSchedule,
  6.     }
  7.    
  8.     // NotReadyTaintTemplateForSched: 集群不健康时的污点
  9.     NotReadyTaintTemplateForSched = &corev1.Taint{
  10.         Key:    clusterv1alpha1.TaintClusterNotReady,  // "cluster.karmada.io/not-ready"
  11.         Effect: corev1.TaintEffectNoSchedule,
  12.     }
  13. )
复制代码
4.2.5 removeCluster - 集群删除
  1. func (c *Controller) removeCluster(ctx context.Context, cluster *clusterv1alpha1.Cluster) (controllerruntime.Result, error) {
  2.     // Step 1: 删除 ExecutionSpace
  3.     if err := c.removeExecutionSpace(ctx, cluster); err != nil {
  4.         klog.ErrorS(err, "Failed to remove execution space", "cluster", cluster.Name)
  5.         return controllerruntime.Result{}, err
  6.     }
  7.    
  8.     // Step 2: 检查 ExecutionSpace 是否已删除
  9.     if exist, err := c.ExecutionSpaceExistForCluster(ctx, cluster.Name); err != nil {
  10.         return controllerruntime.Result{}, err
  11.     } else if exist {
  12.         // 如果还存在,等待下次重试
  13.         return controllerruntime.Result{RequeueAfter: c.CleanupCheckInterval}, nil
  14.     }
  15.    
  16.     // Step 3: 从健康状态缓存中删除
  17.     c.clusterHealthMap.delete(cluster.Name)
  18.    
  19.     // Step 4: 检查集群是否已从所有 Binding 中移除
  20.     if done, err := c.isTargetClusterRemoved(ctx, cluster); err != nil {
  21.         return controllerruntime.Result{}, err
  22.     } else if !done {
  23.         // 如果还有 Binding 引用该集群,等待下次重试
  24.         return controllerruntime.Result{RequeueAfter: c.CleanupCheckInterval}, nil
  25.     }
  26.    
  27.     // Step 5: 移除 Finalizer,允许 Cluster 对象被删除
  28.     return c.removeFinalizer(ctx, cluster)
  29. }
复制代码
删除流程说明

  • 检查依赖:确保没有 ResourceBinding/ClusterResourceBinding 引用该集群
  • 清理资源:删除 ExecutionSpace 及其中的所有 Work 对象
  • 移除 Finalizer:允许 Kubernetes 真正删除 Cluster 对象
4.2.6 monitorClusterHealth - 健康监控

Cluster Controller 启动一个后台 goroutine 定期监控集群健康状态:
[code]func (c *Controller) Start(ctx context.Context) error {    klog.InfoS("Starting cluster health monitor")        // 启动周期性健康检查    go wait.UntilWithContext(ctx, func(ctx context.Context) {        if err := c.monitorClusterHealth(ctx); err != nil {            klog.ErrorS(err, "Error monitoring cluster health")        }    }, c.ClusterMonitorPeriod)

相关推荐

2026-1-17 20:17:05

举报

2026-1-20 01:00:27

举报

很好很强大  我过来先占个楼 待编辑
2026-1-27 06:33:06

举报

2026-1-28 07:25:33

举报

12下一页
您需要登录后才可以回帖 登录 | 立即注册