题干与适用场景
你负责一个 Kubernetes 集群上的分布式训练平台。工作负载由 PodGroup 表示,Pod 需要共享机架或可用区以降低通信延迟;如果同一拓扑域无法容纳至少 minCount 个 Pod,工作负载应保持不可调度。
本文适合平台工程、SRE 和系统设计岗位。假设使用 Kubernetes v1.36 的 alpha Topology-Aware Scheduling,功能默认关闭,且每个 PodGroup 目前只声明一个拓扑约束。
面试官考察点
- 能否区分“跨域均匀分散”的 topology spread 与“同域共置”的拓扑感知 Gang 调度。
- 能否把 PodGroup、节点标签、候选放置、资源评估和绑定原子性连成完整数据流。
- 能否说清
minCount、容量不足、扩容和抢占尚未满足时的状态。 - 能否识别 alpha 功能、异构 PodGroup 与失败回滚的生产风险。
回答前需要澄清的问题
- 要共置在机架、可用区还是 NUMA 域?拓扑键不同,通信和容量假设也不同。
- 是所有 Pod 必须同时启动,还是达到
minCount就可开始?这决定 Gang 策略与弹性。 - Pod 是否同构?不同资源请求会影响候选放置是否可找到,即使理论上存在解。
- 集群是否允许扩容或抢占?v1.36 的拓扑感知调度本身不会为了约束触发抢占。
30 秒回答框架
“我先把目标定义为同一拓扑域内的 group-level feasibility,而不是把副本分散到多个域。Workload 模板生成 PodGroup,PodGroup 使用 gang 和 minCount,节点标签提供唯一拓扑键。调度器生成候选节点子集,检查整个组是否能放入,再给可行放置打分;找不到就让整个组不可调度。控制器和 autoscaler 依据组的资源形状重试,抢占能力单独评估,因为 v1.36 TAS 不会主动抢占。上线前用域容量、节点故障和异构请求演练,并保留 alpha 功能开关。”
分步骤深入解答
1. 明确共置而非分散
topologySpreadConstraints 通过 maxSkew 追求域间平衡;本题要求 PodGroup 的成员共享同一个拓扑标签值。混用两种语义会得到相反的放置结果,因此先把网络延迟目标写成“单域可容纳至少 minCount”。
2. 设计 PodGroup 契约
在模板中声明 Gang 策略、minCount 和单一拓扑键。示意配置如下:
apiVersion: scheduling.k8s.io/v1alpha2
kind: PodGroup
spec:
schedulingPolicy:
gang:
minCount: 4
schedulingConstraints:
topology:
- key: topology.example.com/rack节点必须有稳定、受治理的标签值。PodGroup 只表达放置约束,Workload 控制器仍负责成员生成、版本和生命周期。
3. 解释候选放置算法
调度器先根据资源、污点、亲和性和拓扑键生成候选节点子集,再验证完整 PodGroup 是否能在该子集内满足 minCount,最后对可行放置评分。这个顺序比逐个 Pod 绑定更能避免“前几个 Pod 已占满不同域,剩余成员无处可放”。
4. 处理容量、扩容和抢占
候选域没有足够容量时,整个组保持不可调度;autoscaler 应读取完整组的 CPU、内存、GPU 和域约束,扩容目标不能只看第一个 Pending Pod。v1.36 TAS 不会为满足拓扑约束触发 Pod 或 Workload preemption,因此需要独立的容量预留、队列或明确的上游抢占策略。
5. 处理成员重建与域粘性
如果已有成员在某个域运行,重建的新 Pod 会被强制放回同一域;该域容量不足时,即使其他域有空间也会 Pending。控制器应把这个状态暴露为“域粘性导致等待”,并决定是等待、恢复检查点,还是创建新一代 PodGroup 放宽约束。
6. 评估 alpha 与异构限制
v1.36 的 API 是 alpha 且默认关闭。官方说明中,异构 PodGroup 或存在成员间依赖时,算法不保证找到已有的可行放置。生产闸门应包含版本、feature gate、scheduler plugin、autoscaler 和回滚清单;不能把一次成功调度当作普遍保证。
7. 建立验证和回滚闭环
用同一组训练任务测试单域容量刚好足够、少一个节点、域标签缺失、GPU 不同型和成员重建。记录候选域、可行成员数、Pending 原因、等待时间、跨域流量和训练吞吐。灰度失败时关闭 feature gate 或回到普通 Gang 调度,保留 PodGroup 事件以便审计。
高质量示范回答
我会把目标定义成“至少 minCount 个成员能在同一个拓扑域内同时放置”,而不是用 spread constraint 做均匀分散。Workload 控制器先创建带 gang 策略、minCount 和单一拓扑键的 PodGroup,再生成引用它的 Pod。调度器按资源和节点标签生成候选域,验证整个组能否放入,并只对可行域打分;找不到就让组保持 Pending。Autoscaler 按整组资源形状扩容,抢占单独处理,因为 v1.36 TAS 不会主动抢占。成员重建时保持域粘性,域不足则等待或创建新一代。最后在 alpha 功能开关下演练节点故障、标签缺失、异构 GPU 和回滚,观察等待时间、跨域流量和训练吞吐。
常见错误
- 错误表现:用
maxSkew解释同域共置。失败原因:spread 的目标是分散,和 Gang 共置相反。修正方法:先说明 PodGroup 拓扑键的单域不变量。 - 错误表现:按 Pod 逐个绑定。失败原因:前面的绑定可能消耗多个域的容量,剩余成员无法满足
minCount。修正方法:先生成并评估完整候选放置。 - 错误表现:假设 TAS 会自动抢占。失败原因:v1.36 文档明确指出拓扑感知调度不会触发抢占。修正方法:设计容量预留、队列或独立抢占控制器。
- 错误表现:忽略异构 PodGroup 和 alpha 状态。失败原因:算法不保证找到理论上存在的放置,且功能默认关闭。修正方法:加入版本、feature gate、插件和回滚闸门。
追问及应对
如果同一机架放不下 minCount,但两个机架合计放得下怎么办?
该工作负载的同域不变量未满足,应保持 Pending 或降低 minCount,前提是应用允许弹性。不能静默退化到跨机架,否则通信假设已经改变。
如何让 autoscaler 正确扩容?
把整组资源请求、拓扑键和 minCount 作为一个扩容单元,预测目标域需要的节点类型与数量。扩容后重新生成候选放置,并设置等待上限。
成员重建时为什么不能搬到另一个域?
官方语义要求新成员与已运行成员保持同一拓扑域;迁移会改变网络延迟和共享资源假设。若域永久损坏,应创建新一代 PodGroup,而不是偷偷改变旧组。
这和 topology spread constraints 如何共存?
组内训练成员使用 TAS 共置;跨多个训练作业的副本分布才可使用 spread。把两者放在同一 Pod 上前要验证交集是否为空,否则硬约束会让 Pod 长期 Pending。
什么时候选择普通 Gang 而不启用 TAS?
当跨域通信成本低、域容量经常不足、版本仍在 alpha 灰度,或工作负载不需要共享机架时,普通 Gang 更简单。只有同域带来的吞吐收益能覆盖容量和运维成本时才启用 TAS。