4. 跨集群调度失败:Federation Scheduler 无法将工作负载调度到目标集群

跨集群调度失败是 Federation 控制平面中最常见的故障场景之一。当 Federation Scheduler 无法将工作负载(如 Deployment、Service)调度到预期的目标集群时,通常表现为 Pod 在目标集群中始终处于 Pending 状态,或者工作负载根本未被分发到任何成员集群。本节将系统性地分析 ReplicaSchedulingPreference (RSP) 配置错误导致的调度失败,并提供可操作的排查路径。

4.1 调度失败的核心症状与影响范围

在开始排查之前,首先需要准确识别调度失败的症状。下表列出了不同故障模式下的典型表现,帮助工程师快速定位问题域。

症状 可能原因 影响范围
工作负载未分发到任何集群 RSP 未创建、名称不匹配、Selector 无匹配 全局
副本数分布不均,部分集群为空 权重配置错误、集群标签缺失、资源预留不足 部分集群
Pod 在目标集群 Pending 目标集群资源不足、节点选择器冲突、配额限制 单个集群
调度器日志报错,无分发动作 Federation API 版本不匹配、RBAC 权限不足 控制平面
排查起点: 当发现工作负载未按预期分布时,首先检查 Federation Scheduler 的 Pod 日志。使用 kubectl logs -n kube-federation-system deployment/federation-scheduler 查看是否有明显的错误堆栈或配置解析失败信息。

4.2 ReplicaSchedulingPreference 配置错误深度排查

RSP 是 Federation Scheduler 的核心配置对象,它定义了工作负载在多个集群间的分布策略。配置错误是导致调度失败的首要原因。以下按照配置层级,逐一分析常见错误。

4.2.1 RSP 对象未创建或名称不匹配

Federation Scheduler 通过 RSP 的 spec.targetTemplate.metadata.name 与目标工作负载(如 Deployment)进行匹配。如果 RSP 未创建,或者 RSP 中引用的名称与工作负载名称不一致,调度器将忽略该工作负载。

验证命令:

# 检查是否存在对应的 RSP
kubectl get replicaschedulingpreferences -n <namespace>

# 检查 RSP 的 targetTemplate 是否匹配工作负载名称
kubectl get replicaschedulingpreference <rsp-name> -n <namespace> -o yaml | grep -A5 "targetTemplate"

4.2.2 权重与集群选择器配置错误

RSP 通过 spec.clusters 字段指定目标集群列表,或通过 spec.selector 基于集群标签动态选择集群。以下配置错误最为常见:

  • 权重为零或未定义: 如果某个集群的权重被设置为 0,调度器不会向该集群分发任何副本。
  • 集群标签不匹配: 使用 spec.selector 时,如果成员集群的标签与 RSP 中的 matchLabels 不匹配,该集群将被排除。
  • 集群名称拼写错误: 在 spec.clusters 中直接指定集群名称时,名称必须与 KubeFedCluster 对象中的名称完全一致。

典型错误配置示例:

apiVersion: scheduling.federation.k8s.io/v1alpha1
kind: ReplicaSchedulingPreference
metadata:
  name: my-app-rsp
  namespace: default
spec:
  targetTemplate:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-app  # 正确匹配
  clusters:
    - name: cluster-east
      weight: 0      # 错误:权重为0,不会调度
    - name: cluster-west
      weight: 1
  selector:
    matchLabels:
      region: us-east # 如果 cluster-west 没有此标签,也会被排除

4.2.3 资源预留与配额冲突

即使 RSP 配置正确,调度器在计算副本分布时还会考虑目标集群的资源预留情况。如果目标集群的节点资源不足,或者命名空间配额(ResourceQuota)已满,调度器会跳过该集群。

排查步骤:

  1. 检查目标集群的节点资源:kubectl describe nodes 查看 Allocatable 和 Capacity。
  2. 检查命名空间配额:kubectl get resourcequota -n <namespace> 确认是否达到上限。
  3. 检查 Federation 的 ClusterResourceOverride 策略,确认是否因资源覆盖导致调度器认为资源不足。

4.3 调度失败排查流程图

以下 SVG 图展示了从发现调度失败到定位根因的完整排查路径,帮助工程师按步骤进行系统化诊断。

Federation 跨集群调度失败排查流程图 跨集群调度失败排查流程图 发现调度失败 步骤1: 检查 RSP 对象是否存在 RSP 存在? 创建 RSP 检查名称匹配 步骤2: 检查权重 & 集群选择器 权重 > 0? 调整权重 检查标签匹配 步骤3: 检查资源预留 & 配额 资源充足? 扩容集群/调整配额 检查调度器日志

4.4 调度器日志深度分析

当上述配置检查均无异常时,需要深入分析 Federation Scheduler 的日志。日志中通常包含调度决策的详细记录。以下是一个典型的调度失败日志片段及其解读:

I0825 10:23:45.123456       1 scheduler.go:187] "Processing ReplicaSchedulingPreference" rsp="default/my-app-rsp"
I0825 10:23:45.123567       1 scheduler.go:210] "Clusters matched by selector" clusters="[cluster-east]"
E0825 10:23:45.123678       1 scheduler.go:245] "Failed to schedule for cluster" cluster="cluster-east" error="insufficient resources: requested 2Gi memory, available 1.5Gi"
I0825 10:23:45.123789       1 scheduler.go:280] "No feasible cluster found, skipping scheduling" rsp="default/my-app-rsp"

日志解读:

  • Processing RSP: 调度器已成功读取 RSP 对象。
  • Clusters matched by selector: 通过选择器匹配到的集群列表,此处只有 cluster-east。
  • Failed to schedule for cluster: 调度失败的具体原因——cluster-east 内存不足,请求 2Gi,可用仅 1.5Gi。
  • No feasible cluster found: 所有候选集群均不满足条件,调度被跳过。
关键提示: 如果日志中显示 No feasible cluster found 但集群资源充足,请检查 ClusterResourceOverride 或 ResourceQuota 是否设置了比实际资源更严格的限制。此外,确保 Federation 控制平面与成员集群之间的网络连通性正常,因为调度器需要实时获取集群资源状态。

4.5 常见配置错误速查表

以下表格汇总了 RSP 配置中最容易出错的字段及其正确配置方式,可作为日常运维的快速参考。

配置字段 常见错误 正确配置 验证方法
spec.targetTemplate.metadata.name 名称拼写错误或未定义 必须与工作负载名称完全一致 kubectl get deployment -n <ns> 对比名称
spec.clusters[].weight 权重设置为 0 或负数 权重必须为正整数 kubectl get rsp -o yaml 检查 weight 字段
spec.selector.matchLabels 标签键值对不匹配集群标签 确保集群标签与 selector 一致 kubectl get kubefedcluster -o yaml 查看 labels
spec.totalReplicas 未设置或设置为 0 必须设置期望的总副本数 检查 RSP 的 totalReplicas 字段
spec.rebalance 未启用导致副本不均衡 设置为 true 以启用自动再平衡 kubectl get rsp -o yaml 检查 rebalance 字段

4.6 案例:权重配置错误导致副本分布不均

场景描述: 某团队配置了 RSP,期望将 Deployment 的 10 个副本均匀分布在 3 个集群中。但实际调度后,只有 2 个集群收到了副本,第 3 个集群始终为 0。

排查过程:

  1. 检查 RSP 配置,发现 spec.clusters 中第三个集群的 weight 字段被误写为 0。
  2. 修正权重为 1 后,调度器重新计算分布,副本成功分发到所有集群。
  3. 验证命令:kubectl get pods --all-clusters 确认副本分布已均衡。
最佳实践: 在创建或修改 RSP 后,建议使用 kubectl describe replicaschedulingpreference <name> 查看调度器的决策摘要。如果 Status 字段显示 NoSchedule 或 PartialSchedule,说明存在配置问题,需要立即排查。

4.7 总结与自动化检查建议

跨集群调度失败的根本原因通常集中在 RSP 配置、资源可用性和集群连通性三个维度。建议在日常运维中引入以下自动化检查机制:

  • 配置校验: 使用 kubectl validate 或自定义准入控制器,在 RSP 创建时自动检查权重、名称和标签的合法性。
  • 资源监控: 部署 Prometheus 监控成员集群的资源使用率,当资源不足时提前告警,避免调度失败。
  • 调度器健康检查: 定期检查 Federation Scheduler 的 Pod 状态和日志,确保其正常运行且无错误输出。

通过系统化的排查流程和自动化检查,可以大幅降低跨集群调度失败的概率,提升 Federation 控制平面的稳定性。