一万台机器可以组成一个集群,也可以组成十个集群。两种方案都能提供万级计算资源,但它们的调度边界、故障范围、运维方式和研发成本完全不同。
大规模集群设计的核心,是让资源规模、状态变化和故障影响保持在可控制的边界内。节点数量只是其中一个维度。
本文以 Kubernetes 为主要实现背景,讨论通用在线服务、批处理和 AI 训练三类负载。架构原则也适用于其他集群管理系统,但具体 API、组件和参数不能直接套用。文中的容量数字均为明确假设下的估算;业界案例按原始资料的时间和口径介绍,资料核对日期为 2026-11-08。
一、万级规模究竟难在哪里 #
1.1 节点规模不等于系统压力 #
比较两个假设集群:
| 维度 | 集群 A:大任务训练 | 集群 B:在线服务与短任务 |
|---|---|---|
| 节点数 | 10,000 | 10,000 |
| 平均每节点 Pod 数 | 2 | 50 |
| 总 Pod 数 | 20,000 | 500,000 |
| 生命周期 | 以小时、天为主 | 大量分钟级任务,频繁发布 |
| 调度重点 | GPU、网络拓扑、整组资源 | 创建吞吐、碎片、租户公平性 |
| 潜在瓶颈 | 集体通信、训练数据、检查点 | API、对象缓存、调度队列、服务发现 |
即使节点数相同,两个集群的对象规模和控制面负载也可能相差一个数量级。A 的大任务失败还可能造成更高的单次业务损失,不能据此认为 A 更容易运维。
设计前至少量化五组数据:
- 存量:Node、Pod、Service、EndpointSlice、Secret、CRD 实例数量及对象大小。
- 变化量:每秒创建、删除、状态更新,以及发布、扩容时的峰值。
- 订阅量:Watch 连接数、订阅范围、每次更新需要通知的消费者数。
- 数据面负载:连接数、包速率、跨机架流量、镜像和训练数据吞吐。
- 恢复目标:故障后允许损失多少容量、多久恢复、能容忍多少数据回退。
1.2 从四个简单估算开始 #
心跳写入。 Kubernetes 使用 Node 状态和 Lease 表示节点心跳;kubelet 默认每 10 秒更新一次 Lease。按此配置,10,000 个节点仅 Lease 就约有 10,000 / 10 = 1,000 次更新/秒,尚未包含 Pod 状态及其他写入。Node Status 官方说明
状态传播。 假设某类对象每秒更新 200 次,每次编码后约 4 KiB,并且有 1,000 个消费者需要接收全部更新,则应用层发送量约为:
200 × 4 KiB × 1,000 ≈ 781 MiB/s
这是未计压缩、协议开销和筛选效果的示意模型。它说明:即使底层数据库写得动,API Server 的编码、复制和发送仍可能先达到瓶颈。
全量同步。 假设有 400,000 个 Pod,每个对象序列化后平均 8 KiB,一次全量 LIST 的数据量就约为 3.05 GiB。本地反序列化、索引和中间对象还会增加内存消耗;多个控制器同时重启,会放大这项成本。
故障恢复。 假设 500 个节点失效,每节点有 40 个需要重建的 Pod,共产生 20,000 个 Pod 的恢复需求。即使有效调度吞吐稳定为 100 Pod/s,仅调度阶段也至少需要 200 秒,后面还有镜像、网络、卷和应用启动。
因此,万级集群既要能容纳对象,也要能承受变化,更要能在故障后及时恢复。
1.3 上游边界与厂商能力要分开看 #
Kubernetes 上游大集群文档列出的设计范围包括:不超过 5,000 个节点、150,000 个 Pod、300,000 个容器,以及每节点不超过 110 个 Pod。这些约束需要同时满足,不能用 5,000 × 110 推导总 Pod 容量。上游大集群说明
超过该范围并不等于一定无法运行,但需要额外的版本验证、系统改造或厂商支持。后文的 7,500、100,000、130,000 节点案例,各有不同负载和实现条件,不能视为原生 Kubernetes 的统一承诺。
二、先选架构:单个大集群,还是多个 Cell #
2.1 三条路线 #
| 路线 | 基本结构 | 主要收益 | 主要代价 | 适合场景 |
|---|---|---|---|---|
| 单个超大集群 | 一套逻辑控制面管理万级节点 | 资源池大,单个任务容易取得大量资源 | 控制面扩展复杂,故障和变更影响广 | 强耦合训练、大规模同域计算 |
| 多个独立集群 | 按业务、地域或环境分别建设 | 隔离清晰,迁移可以分阶段进行 | 容量割裂,配置与运维重复 | 业务边界稳定、团队独立 |
| Fleet + Cell | 全局平台管理多个相对独立的执行单元 | 统一入口和资源治理,同时控制局部规模 | 需要全局放置、跨集群发布与服务治理 | 万级总规模的通用平台 |
这里把 Cell 定义为一个具有独立控制面、状态存储和局部运维能力的资源单元。它通常对应一个 Kubernetes 集群,也可以对应经过设计的其他隔离边界。
对于通用业务平台,一个合理起点是多个 Cell,具体大小由容量测试和可接受故障范围决定。对于需要在同一低时延网络域内占用数千台机器的任务,单个大集群可能更合适。
Cell 不能随意切小。 如果一个任务需要 3,000 个节点,而每个 Cell 只有 2,000 个节点,跨 Cell 执行就需要训练框架、网络、资源协同和恢复机制共同支持,统一门户无法自动解决这些问题。
2.2 多集群增加的复杂度必须有明确归属 #
拆分后,需要逐项回答:
- 放到哪里:依据容量、硬件、配额、数据位置和网络成本选择 Cell。
- 如何发布:按 Cell 分批推进,避免一次错误覆盖所有集群。
- 如何访问:通过全局入口、网关或服务发现找到目标,明确超时和跨区成本。
- 如何存取数据:业务数据是否已有复制,目标集群能否访问相应卷或对象。
- 谁能操作:全局身份与每个 Cell 的授权如何映射。
- 如何接管:原集群不可达时,谁有权创建新实例,怎样避免重复执行。
这些问题可以通过平台标准化处理,但不能仅靠给多个集群安装相同组件完成。
2.3 故障隔离要覆盖共享依赖 #
四个 Cell 即使使用独立 etcd,如果共用一个无冗余的镜像仓库、Webhook、身份服务或出口网关,仍可能同时失效。
隔离设计要从业务请求出发,沿依赖链检查:控制面、网络出口、DNS、制品仓库、存储、密钥服务、监控和发布系统。能接受的共享依赖,需要有对应的容量、降级和恢复方案。
三、参考架构:全局决策与局部执行 #
下面是一种面向通用业务和批处理的参考结构,不代表某家公司的内部实现。
3.1 全局层管理意图和摘要 #
全局层适合负责租户、配额、任务归属、跨 Cell 发布、容量汇总和放置策略,不应默认复制每个 Pod 的所有状态。
例如,全局层只需知道某个 GPU 池还有多少可用容量、哪些任务等待准入,以及各 Cell 的健康状态。Pod 的瞬时探针结果、容器退出详情和局部重试由本地处理,必要时再下钻查询。
这样既减少状态传播,也避免全局层成为所有操作的同步依赖。
3.2 Cell 内部的控制路径 #
API Server 统一处理控制请求,调度器和控制器通过 API 读写状态,通常不直接操作 etcd。负载均衡入口需要检查后端就绪状态,并妥善处理大量长连接及重连。
业务请求走网关、Service 与 Pod 网络,通常不经过 API Server。控制路径与业务流量路径应分别规划容量,避免把“API 可用”当作“业务可用”的充分条件。
3.3 局部层形成闭环 #
每个 Cell 内部保留完整的 API、调度、控制器、网络和基础监控能力。全局平台暂时不可用时,已经下发的工作负载应能继续运行,并在本地完成权限允许的副本补齐和故障处理。
需要明确区分两种能力:
- 继续执行已有意图:通常可以依赖本地控制器完成。
- 接受新的全局决策:例如借用其他租户配额、跨 Cell 接管任务,需要一致的授权与所有权协议。
不能为了提高可用性,让各 Cell 在失联后无限自主领取同一份任务。
3.4 放置需要预留和确认 #
容量摘要有延迟。如果多个提交者都看到“还剩 100 张 GPU”,可能同时把任务放进去。
一种可实施的协议是:
- 全局层选择候选 Cell,生成唯一任务 ID 和放置代次。
- 本地层按任务 ID 幂等申请配额或预留,返回是否接受。
- 接受后启动任务;失败则释放预留,按退避策略选择其他位置。
- 预留具有有效期,超时回收;任务重试前确认旧执行权是否失效。
全局选择可以基于最终一致的摘要,但真正消耗资源时必须由权威方确认。跨集群任务还需要外部副作用的幂等或 fencing,后文会进一步讨论。
四、控制面:从“请求能处理”到“过载可控制” #
4.1 API Server:先分清读、写和分发 #
API Server 的负载至少包括认证授权、准入、读写存储、缓存维护、对象编码和 Watch 分发。
增加 API Server 副本可以分摊部分连接和计算,但每个副本也会维护缓存、订阅底层变化。后端写入、网络出口或热点对象已经饱和时,继续加副本的收益会下降。
扩容前应区分:
| 现象 | 优先检查 | 对应措施 |
|---|---|---|
| LIST 导致内存和延迟突增 | 对象规模、并发全量读取、缓存命中路径 | 缩小查询范围,分页或流式读取,错峰初始化 |
| 写请求延迟高 | Webhook、etcd 提交、热点对象冲突 | 缩短同步链路,减少无效更新,降低竞争 |
| CPU 高但存储正常 | 编解码、Watch 扇出、授权开销 | 限定订阅范围,分层分发,按证据扩副本 |
| 请求排队、429 增加 | 请求来源、优先级、并发预算 | 分类限流、退避、冻结非关键变更 |
现代 Kubernetes 已对缓存读路径进行了多轮优化。以 v1.34 的公开说明为例,一致性缓存读取、缓存快照和流式响应分别减少底层读取、支持历史版本或分页访问、降低响应编码内存;它们解决的是不同环节。是否生效取决于实际版本、请求语义及相应功能状态,不能笼统认为“LIST 一定访问 etcd”或“LIST 永远只访问缓存”。API Server 缓存优化说明
4.2 LIST / Watch:减少全量和广播 #
大规模下最危险的组合是:对象多、消费者多、消费者同时重启。
控制器应优先采用以下方式:
- 进程内复用 SharedInformer,避免多个模块独立订阅同一范围。
- 按实际职责限定 namespace、资源类型和 selector;筛选是否能利用索引,需要实测。
- 重连、初始化和周期任务加入随机抖动,避免整点请求峰值。
- 只需元数据时,评估 metadata-only 访问及客户端支持,减少对象体积。
- 处理过期
resourceVersion和重新同步,不能假设事件历史永久保留。 - 对相同对象的多次变化进行队列合并,以当前状态执行幂等 reconcile。
Informer 的周期性 resync 通常是把本地缓存对象重新交给处理逻辑,不等于每次都向 API Server 全量 LIST。诊断压力时应区分 resync、Watch 重连和重新 LIST。client-go SharedInformer 接口说明
对于天然需要向大量节点广播状态的组件,可以增加专用分发层。Calico Typha 就位于数据存储与大量 Felix 实例之间,缓存状态、去重事件,再向下游分发,以减少对 API Server 的重复订阅。Typha 架构说明
分发层本身也必须具备多副本、限流和重连保护;否则只是把原来的瓶颈搬了位置。
4.3 APF 与客户端退避共同控制过载 #
API Priority and Fairness(APF)按照请求流分类、分配并发份额并排队,目的是在过载时保护关键流量。APF 官方说明
可根据实际身份和请求类型,区分节点存活、关键控制器、普通发布、批处理提交及管理查询。配置时需要验证分类命中情况,防止一个批处理系统因为共用高权限身份而获得过高优先级。
但 APF 不会增加系统总吞吐。客户端收到 429 或超时后立即重试,会把排队变成重试风暴。客户端应设置有上限的并发、指数退避和随机抖动,并遵循服务端重试提示。
客户端限速、服务端公平排队、入口任务准入需要同时存在。 只在 API Server 上放宽并发,可能把积压继续推向 etcd。
4.4 etcd:先减少写放大,再评估存储扩展 #
etcd 的关键约束包括共识网络往返、持久化延迟、数据库大小和状态变更速率。增加成员主要提高容错能力,不能把一个 Raft 组变成多分片写入系统;成员增多还会增加复制成本。etcd FAQ、硬件建议
生产设计可以按三个层次推进:
第一层:保护存储。 独立资源和低延迟磁盘,避免与镜像解压、日志写入竞争;成员放在低时延且相互独立的故障域。跨地域容灾通常更适合独立集群与异步数据复制,而不是让同一个 etcd 共识组跨高时延广域网。
第二层:减少状态写入。 控制器只在字段实际变化时更新;避免每次 reconcile 都刷新时间戳;不把日志、追踪和高频进度采样放入 CRD。需要注意 Patch 不必然减少更新次数或底层版本产生,首先要消除无意义写入。
第三层:按瓶颈选择拆分。 优先评估拆 Cell;确需扩大单集群时,再考虑按资源隔离存储,或使用专门的可扩展后端。
例如,API Server 的 --etcd-servers-overrides 支持对特定内置资源指定后端,可用于评估把高噪声 Events 与核心状态分开。这是按资源类型路由,不是对一个 Pod 集合自动分片;涉及不同 API 组时还必须核对实际资源路径和版本行为。API Server 参数说明
无论采用哪种结构,都要监控 WAL fsync、backend commit、请求延迟、数据库占用、leader 变化和待处理提案;定期压缩历史、逐成员维护碎片,并验证快照恢复。正常写入快不代表备份恢复快。
4.5 Controller:多副本不等于并行扩展 #
很多控制器通过 leader election 选出一个活跃实例。把副本从 2 个加到 10 个,可能只增加备用实例和缓存成本。
需要提高吞吐时,先检查工作队列积压、单次 reconcile 耗时和外部依赖,再决定增加 worker,还是按租户、namespace 或业务键分片。
分片必须保证对象归属明确,迁移时有交接协议。否则两个实例可能同时更新同一对象,触发冲突、重试和额外 API 请求。热点也可能来自一个共享的配额对象:将所有任务计数更新集中到同一条记录,会形成新的串行点。
4.6 Webhook:同步依赖会放大故障 #
Webhook 位于 API 写入路径。变更流量达到数百次/秒后,即使单次调用只是额外几十毫秒,也会占用大量并发;一旦依赖变慢,创建、更新乃至故障恢复都可能排队。
设计要点是:限定匹配范围、短超时、多副本、避免同步调用不稳定外部服务,排除自身恢复所需资源,并保持变更幂等。修改类 Webhook 可能串行调用并被再次调用,更需要控制数量。Webhook 官方最佳实践
失败策略需要按用途决定:安全边界通常要求拒绝不确定请求;可选的标注或增强功能可以评估失败放行。无论哪种,都应提前演练故障和应急修改路径。
五、调度与资源治理:吞吐、利用率和公平性的取舍 #
5.1 调度器的压力来自搜索空间和约束 #
可用下面的示意关系理解一次调度的计算成本:
调度计算量 ≈ 检查的候选节点数 × 单节点约束评估成本
+ 打分、抢占与状态维护成本
这不是算法复杂度的严格公式,但能帮助定位优化方向。节点多、Pod 多、跨 Pod 约束复杂、抢占频繁,都可能使单次决策变慢。
优化顺序通常是:
- 用清晰的节点池、硬件标签与约束表达资源需求,减少不必要的昂贵规则。
- 检查亲和性、反亲和性、拓扑分布和自定义插件的开销。
- 在吞吐与放置质量之间调整候选节点搜索范围。
- 仍无法满足目标时,再考虑按负载拆调度器或采用分布式调度架构。
percentageOfNodesToScore 允许调度器在找到足够多的可行节点后停止搜索。它不是“先随机抽固定百分比节点”,也不保证每次只检查这些节点;约束很紧时仍可能扫描很大范围。数值过低还可能损害放置质量和资源利用率。调度器性能调优
5.2 多调度器首先要解决竞争 #
给多个 scheduler 使用不同的 schedulerName,可以分担不同 Pod 的决策,但如果它们共享节点资源,各自的缓存可能同时认为同一节点有剩余容量。
并行调度需要额外机制:按资源池划分所有权、资源预留、冲突检测、失败回退,或者具有一致性校验的提交阶段。单纯启动多个实例,无法自动得到线性吞吐提升。
分片还会带来容量碎片。把在线与离线资源池完全隔离容易控制,却可能降低共享效率;允许共享则需要优先级、借用、回收和干扰隔离一起工作。
5.3 队列准入与节点放置是两层问题 #
一个需要 128 个 GPU worker 的任务,如果只有 100 个 worker 获得资源并长期等待,其占用可能挤压其他任务。
因此,批处理通常需要先决定“现在是否允许整个任务进入执行”,再决定“每个 Pod 放到哪个节点”。
| 层次 | 主要问题 | 常见机制 |
|---|---|---|
| 任务准入 | 谁可以开始,占用多少配额 | 队列、优先级、公平共享、配额借用 |
| 组级协同 | 最小运行集合能否成立 | Gang、预留、超时撤销与重新排队 |
| 节点放置 | 资源具体落在哪里 | Filter / Score、拓扑、设备与卷约束 |
| 执行管理 | 启动失败和运行中失败怎么办 | Job 控制器、重试、检查点、弹性成员 |
Kueue 主要管理配额和任务准入,不替代 kube-scheduler;Volcano 提供面向批处理的调度能力,包括 Gang 等策略。两者职责和集成方式不同,选型应从所需语义出发。Kueue 概述、Volcano 架构
Gang 不意味着所有容器在物理时钟上同时启动。系统仍要处理镜像、设备、网络或应用初始化失败,以及部分成员就绪后的回收问题。Kueue 的 all-or-nothing 实现也区分配额准入、拓扑约束与就绪超时,不能仅把“配额够”视为“所有 Pod 一定能落地”。Kueue all-or-nothing 说明
5.4 GPU 调度需要看到通信拓扑 #
“还有 1,024 张 GPU”不足以判断能否运行一个 1,024 卡训练任务,还要看:
- GPU 型号、显存和切分方式是否符合任务要求。
- 同机 GPU 的互连、GPU 与 NIC 的 PCIe / NUMA 亲和关系。
- 节点是否位于合适的机架、网络块和 RDMA 域。
- 对应网络和存储是否有足够吞吐。
- 节点、网卡和 GPU 的健康状态是否可信。
对于强集体通信任务,资源分散造成的通信损失,可能超过更早启动带来的收益。拓扑感知需要调度器、设备管理、网络和训练框架使用一致的拓扑定义。
5.5 利用率不能只看平均 CPU #
资源利用率需要同时观察 requests、实际使用、可回收资源和业务 SLO。在线与离线混部可以使用空闲算力,但需要明确离线任务的回收时限,并隔离 CPU、内存、磁盘和网络干扰。
常见策略是:在线负载保留保障,离线负载借用可回收资源;高峰来临时按顺序终止或缩减离线任务。内存、GPU 显存与设备占用的回收方式不同,不能把 CPU 超卖经验直接套过去。
对 AI 平台,还应关注完成一个有效任务的 GPU 小时、训练有效计算时间和重跑成本。GPU 显示“忙”可能只是通信等待,不能直接等同于产出高。
六、网络:转发路径和状态传播都要扩展 #
6.1 先规划地址,再扩机器 #
IPAM 既是容量规划,也是启动路径上的依赖。
例如,某方案为每个节点分配一个 /24 PodCIDR,那么 10,000 个节点需要预留约 256 万个地址,即使每节点只运行几十个 Pod。云上按网卡、前缀或地址池分配时,还存在预热、配额和回收延迟。
需要一起核算:Pod、Node、Service、负载均衡器和升级期间临时资源的地址需求,以及与 VPC、VPN、其他集群的网段冲突。IPv6 可以缓解地址空间问题,但不会自动消除云 API 限速和 IPAM 控制器瓶颈。
6.2 EndpointSlice 降低的是更新粒度 #
服务发现需要把后端变化送到代理和其他消费者。大型后端集合如果每次变化都传播整个列表,会形成明显放大。
EndpointSlice 把后端拆成多个对象,默认每片最多 100 个端点,变化时通常只需更新相关切片。它减少单次传播的数据量,但如果所有节点仍订阅同一变化,消费者数量带来的扇出仍然存在。EndpointSlice 官方说明
应同时治理 Service 数、端点数、变化速率和订阅范围。把一个巨大 Service 拆成多个 Service,也会增加对象和配置开销,必须验证实际收益。
6.3 数据面选型需要测收敛,而不只是测稳态 QPS #
iptables、nftables、eBPF 或其他实现,各有版本和部署条件。选型时至少测量:
- Service 与端点增长后的规则或映射占用。
- 批量端点变化后,流量转发需要多久收敛。
- 新建连接速率、conntrack 占用、SNAT 端口和丢包。
- Overlay 封装、MTU、路由规模与跨机架带宽。
- 节点 CPU 被网络处理占用后,对业务延迟的影响。
eBPF 可以优化某些转发和策略路径,但仍依赖内核、映射容量、控制器及状态分发。更换转发技术不能替代整个网络的容量设计。
6.4 DNS 和策略分发容易成为隐藏瓶颈 #
大量短连接、低命中缓存、过多 search domain 尝试和失败重试,都可能放大 DNS 查询。可以根据负载评估节点本地缓存、合理 TTL 和 CoreDNS 扩展,同时观察缓存冷启动与失效时的上游压力。
网络策略也要预算。细粒度身份或策略数量增长后,控制器计算、下发和节点应用都需要时间。验收指标不仅是最终规则正确,还包括节点重启和策略批量变更时,多久恢复到正确状态。
七、存储与启动:避免把扩容变成集中读写风暴 #
7.1 把 Pod 启动链路拆开计时 #
提交 → 准入 → 控制器创建 → 排队与调度 → 卷准备
→ 镜像获取与解压 → 容器启动 → 应用就绪 → 接收流量
这些步骤可能部分并行。分阶段计时的目的,是识别真正的关键路径。
如果 Pod 已经绑定节点,但等待镜像十分钟,扩 scheduler 没有直接帮助;如果都卡在 PVC 创建,优先检查 CSI 和存储 API。
7.2 镜像与模型分发 #
假设 10,000 个节点冷启动时都要下载同一份 5 GiB 内容,逻辑下载量约为 48.8 TiB。理想情况下,100 Gbit/s 源站出口单独承担全部传输,也需要约 72 分钟;实际还会有协议、带宽竞争和解压开销。
减少这个瓶颈可以组合使用:
- 分地域或 Cell 的镜像代理与缓存,减少跨域重复下载。
- 节点池预热,只预热实际可能使用的镜像与模型。
- 使用内容摘要固定版本,保证缓存复用和回滚可重复。
- 在适合的网络与磁盘条件下引入 P2P 分发。
- 对扩容和发布限速,同时约束仓库出口、节点磁盘及解压 CPU。
P2P 用节点的上传带宽和磁盘换取源站减压,仍要处理热点、种子容量、跨区流量与缓存丢失。相关机制可结合本站的 Dragonfly 架构与原理 和 性能验证与故障排查 阅读。
7.3 CSI 的吞吐与拓扑约束 #
卷创建、Attach、Detach、挂载与回收各有独立队列和外部 API 限额。一次驱逐大量有状态 Pod,可能在计算资源仍充足时耗尽这些能力。
需要按存储类型验证:
- 单节点卷数量和控制器并发上限。
- 存储所在 zone 与 Pod 放置是否匹配,是否需要延迟绑定。
- 故障节点的卷多久能安全解除并重新挂载。
- 云 API 被限流或超时时,重试是否幂等且有退避。
- 本地盘数据丢失后,由业务副本还是数据重建机制恢复。
存储可用性与集群可用性是两件事。目标 Cell 有空闲节点,不代表能够直接挂载原 Cell 的卷。
7.4 训练数据与检查点 #
大规模训练常见两类冲击:启动时集中读取数据或模型,运行中集中写检查点。
可将持久化数据存储与本地缓存分层,减少远端重复读取;对检查点采用分片、错峰或异步写入,并为恢复读取预留带宽。小文件很多时,还要测元数据操作和目录扫描,不能只看顺序吞吐。
异步写入需要定义何时才算检查点完成,例如所有分片持久化后再提交完整性标记。否则故障恢复可能读到不完整但看似存在的版本。
八、可靠性:故障是常态,相关性决定影响面 #
8.1 硬件越多,系统越需要持续修复 #
假设每个节点平均每年出现一次需要替换或人工介入的事件,10,000 个节点平均每天约有 27 次。这只是说明规模效应的假设,不是行业故障率统计。
平台应具备健康检测、节点隔离、自动维修和受控替换能力,并为误判设置边界。例如单机 GPU 异常可触发隔离,但某个探针服务同时报告几千台异常时,应先判断探针或共享网络是否故障。
8.2 故障域比节点数更重要 #
单节点故障、交换机故障、可用区故障和错误配置覆盖的节点数量不同,恢复方式也不同。
| 故障域 | 主要设计手段 | 容易遗漏的条件 |
|---|---|---|
| 节点 | 副本、健康检查、替换、可重试任务 | 本地数据与设备状态 |
| 机架 / 网络块 | 拓扑分散、网络冗余 | 副本是否实际落在不同物理域 |
| 可用区 | 多区部署、流量切换、独立容量 | 存储复制、跨区带宽、剩余区容量 |
| Cell | 独立控制面、分批发布、任务迁移 | 共享依赖及跨集群执行权 |
| 地域 | 独立地域与业务级复制 | 数据一致性、RPO、全局入口 |
Cell 数量本身不能证明跨区容灾。四个 Cell 如果每个都均匀分布在三个可用区,损失一个可用区仍可能影响每个 Cell 约三分之一的容量。
8.3 恢复需要容量和吞吐两种余量 #
假设某资源池总容量为 C,需要承受比例为 f 的容量故障,在不借助外部扩容、超卖或业务降级的条件下,应满足:
故障后的业务资源需求 ≤ C × (1 - f)
这意味着,若三个等容量可用区要在损失任一区后保持相同需求,稳态需求不能超过总容量约三分之二。真实约束还要按 CPU、内存、GPU 型号、网络和卷位置分别计算,不能只看总核数。
即使剩余容量足够,恢复速度还受到调度、镜像、IPAM、CSI 和应用启动的共同限制。故障后把所有补建请求一次性放出,可能让原本健康的基础设施也过载。
恢复控制应按任务优先级分批推进,并为控制面、DNS、网络和监控保留资源。高优先级服务优先恢复,低优先级任务可以延后或重新排队。
网络分区还可能造成大面积误判。Kubernetes 对节点异常的处理包含按可用区调整驱逐速率等保护,修改前应验证目标版本的行为。过于激进的驱逐和自动维修,可能把控制路径失联扩大为真实业务中断。节点控制器与驱逐限速
8.4 失联不等于停止运行 #
控制面不可达时,部分已运行容器和已有网络状态可能继续服务,但扩缩容、新调度和依赖控制器的操作可能受阻。不能据此保证业务无影响,也不能直接认定失联节点已经停止执行。
对于跨 Cell 接管、数据库主实例或带外部副作用的任务,需要执行权隔离:例如由权威服务颁发递增 epoch,并由存储或业务端拒绝旧 epoch 的写入;必要时配合基础设施层断电、断网或存储 fencing。
如果只是在另一个集群重建同名任务,而旧任务仍在运行,就可能重复消费、重复扣费或产生数据冲突。任务提交幂等与外部写入幂等都需要覆盖。
8.5 PDB、备份和副本各自解决什么 #
PodDisruptionBudget 主要限制通过 Eviction API 发起的自愿中断。它不能阻止物理故障,也不会自动限制 Deployment 的滚动更新;直接删除 Pod 也可能绕过它。中断与 PDB 官方说明
etcd 快照保存的是 Kubernetes 控制状态,不包含持久卷中的业务数据,也不能代替镜像、密钥和外部配置备份。恢复演练应同时验证:
- 控制状态和业务数据各自的 RPO,即允许回退多久的数据。
- 从开始恢复到业务可服务的 RTO,而不只是 etcd 启动耗时。
- 控制器缓存重新同步,及恢复后与云资源、卷、负载均衡器的状态对齐。
- 证书、加密密钥、制品和恢复工具是否可用。
如果系统运行依赖集群内的 DNS、仓库和 Webhook,而这些组件的修复又依赖正常控制面,就可能出现恢复闭环。应保留能打破该依赖的独立运维入口和引导资源。
九、可观测性与运维:管理总量,也管理变化 #
9.1 监控本身需要容量模型 #
假设每个节点贡献 5,000 条活跃时间序列,10,000 个节点就有 5,000 万条;每 15 秒采集一次,约为 333 万样本/秒,尚未包含业务指标和副本冗余。
需要控制标签基数,避免把用户 ID、请求 ID 等无界维度直接放入指标。短生命周期 Pod 还会增加序列 churn,即使某一时刻活跃序列不高,长期索引和存储压力也可能很大。Prometheus 指标命名建议
一种可行结构是本地分片采集与告警,全局保留聚合视图,详细数据按需查询。Prometheus 的层级联邦体现了这种“局部细节、全局聚合”的方式;长周期存储也可根据需要采用远端存储体系。Prometheus 联邦说明
日志要设置采样、保留和故障期间的限流,防止异常堆栈风暴拖垮日志系统;关键告警与日志入口应避免完全依赖正在故障的 Cell。
9.2 从用户可感知的结果建立 SLO #
只监控组件 CPU 无法判断集群是否满足业务需求。更有用的指标包括:
| 目标 | 指标示例 | 需要限定的条件 |
|---|---|---|
| API 可用 | 按资源、动词、客户端统计延迟和错误 | 读写分开,排除长连接持续时间的混淆 |
| 调度及时 | 可调度 Pod 的排队和绑定 P95 / P99 | 区分配额不足、资源不足与系统故障 |
| 启动及时 | 提交到 Ready、Ready 到接收流量 | 镜像冷热、卷类型、应用类别 |
| 故障可恢复 | 失效到替代实例恢复服务 | 故障域、业务规模与剩余容量 |
| 资源有效 | 任务完成时间、有效 GPU 小时、成本 | 区分等待、重跑、通信和有效计算 |
在这些结果指标下面,再关联 API 排队、控制器队列、etcd 延迟、DNS 错误、镜像吞吐、CSI 队列和节点压力,才能形成可定位的证据链。
9.3 一万节点上的小开销也很大 #
一个每节点预留 0.1 CPU、200 MiB 内存的 DaemonSet,在 10,000 个节点上合计就是 1,000 CPU 和约 1.91 TiB 内存。
日志、监控、网络、安全代理通常不止一个。应核算它们的总 requests、实际开销、Watch 连接、日志量及升级产生的临时副本。部署一个全节点组件,本质上也是一次集群级容量变更。
9.4 变更需要跨层预算 #
节点替换、业务发布、镜像预热、卷迁移和批任务扩容会消耗共同资源。每个系统单独设置“最多 100 个并发”,叠加后仍可能过载。
平台可以按 Cell、可用区和共享依赖建立变更预算:例如同时限制替换节点数、Pod 创建速率、镜像出口和卷操作数。预算应根据实时排队、错误率和延迟自动收紧,异常时暂停后续批次。
升级可以按测试集群、少量节点池、单 Cell、多个 Cell 逐步推进。控制面、CNI、CSI、内核和设备插件的兼容性需要整体验证,不能把它们当作互不相关的升级。
9.5 多租户隔离覆盖资源与 API #
namespace 和 RBAC 提供组织与授权边界,但不是完整的资源或强安全隔离方案。还需要组合配额、LimitRange、优先级、网络策略、存储限制、节点隔离和运行时隔离。
平台租户配额不仅要约束 CPU、内存、GPU,也要覆盖 Pod、Service、PVC、CRD 实例,以及任务提交并发等 API 成本。否则一个租户可以在计算占用很低时,通过大量对象和状态更新影响整个控制面。
十、业界方案:看架构选择,也看成立条件 #
下面的数字分别属于论文描述、历史生产实践、厂商能力声明或实验结果,不能混为同一条规模排名。
10.1 Google Borg:资源管理是一整套系统 #
Google 2015 年的 Borg 论文描述了每个集群可达数万台机器的管理方式,通过准入控制、任务装箱、超卖和带隔离的机器共享提高利用率。Borg 原始论文介绍
值得借鉴的是,把资源准入、任务优先级、共享和隔离作为整体设计。它说明大资源池能够成立,但不意味着把 Borg 的节点数量直接套到 Kubernetes 就能得到相同行为。
Google 的 Omega 论文则研究了共享状态与乐观并发调度:允许多个调度器并行决策,再处理状态竞争。这提供了扩展调度计算的思路,同时要求评估冲突和重试成本;它不是给普通 scheduler 增加几个副本就能获得的行为。Omega 原始论文介绍
10.2 OpenAI:7,500 节点有具体负载前提 #
OpenAI 在 2021 年公开了 Kubernetes 扩展到 7,500 节点的实践。其许多任务使用单 Pod 占据整节点,减少了装箱和碎片压力;当时的集群具有全对分带宽,也较少依赖机架拓扑调度。文章讨论了端点传播、监控和节点加入带来的压力。OpenAI 原文
这个案例说明,负载建模比节点数字更有解释力。高密度微服务、大量短任务或网络过订阅环境,需要重新验证。原文中的优化效果也对应当时的版本和特定问题,不宜作为今天所有集群的通用倍数。
10.3 Google GKE:极大单集群需要系统性改造 #
Google 在 2025-11-21 的技术文章中介绍了 130,000 节点实验集群,并明确区分当时已支持的 65,000 节点规模。文章披露,该实验使用基于 Spanner 的专有键值存储,并结合 API 缓存优化与 Kueue 任务管理。GKE 实验技术文章
这条路线包含底层状态存储及上层控制逻辑的共同演进。它证明专门实现可以突破上游常规规模边界,但不能推导为“给原生 etcd 加几台机器即可复现”。上述数字描述原文当时的条件,不代表对当前所有 GKE 配置的能力承诺。
10.4 AWS EKS:使用厂商能力仍要验证自己的负载 #
AWS 在 2025 年 7 月宣布 EKS 单集群支持最多 100,000 个 worker 节点,面向超大 AI / ML 负载。AWS 原始公告
使用这类能力时,需要明确适用地域、接入方式、配额和配置条件,并分别验证 Pod 密度、对象变化速率与恢复目标。节点数上限不能替代对网络、GPU 库存、IPAM、存储和镜像分发的容量评估。
10.5 字节跳动 KubeWharf:分别处理状态和调度瓶颈 #
KubeWharf 的公开项目展示了两条方向:
- KubeBrain:在 API Server 与底层键值存储之间实现所需的状态存储接口,将后端扩展能力与 Kubernetes 元数据管理连接起来。KubeBrain 项目
- Gödel Scheduler:通过并发决策、乐观并发思路及 Unit / Pod 两层语义改进调度,公开架构中包含 Dispatcher、Scheduler 和 Binder 分工。Gödel 项目
它们体现的是对不同瓶颈分别改造。引入前仍要核对公开版本的兼容范围、一致性行为、故障恢复和维护能力;公司内部实践规模不能直接当作开源版本的交付承诺。
10.6 这些实践可以归纳为三条工程路径 #
| 路径 | 解决的问题 | 需要承担的成本 |
|---|---|---|
| 缩小局部规模 | 用 Cell 隔离控制面与故障,限制单元容量 | 全局放置、跨集群治理、容量碎片 |
| 扩大单集群能力 | 改进缓存、存储、调度和广播路径 | 深度研发、一致性验证、长期升级维护 |
| 降低单位负载成本 | 整节点任务、减少约束、削减状态与无效更新 | 对业务模型和功能有约束 |
成熟平台通常组合使用这些方式。选择依据应是任务规模、业务 SLO、故障预算和团队能力,而不是追求最大的单集群节点数。
十一、一套可落地的万节点平台示例 #
假设平台需要管理 10,000 个 worker 节点,承载在线服务与可重试批任务,没有必须跨数千节点运行的单个训练任务。可以从下面的方案开始验证。
11.1 容量与边界 #
| 项目 | 示例设计 | 验证重点 |
|---|---|---|
| Cell 数量 | 4 个,每个约 2,500 节点 | 单 Cell 故障范围是否可接受 |
| Pod 存量 | 平均每节点 40 个,包含系统 DaemonSet | 每 Cell 约 100,000 Pod,另留发布和故障余量 |
| 全局职责 | 任务归属、配额、发布与容量放置 | 摘要延迟、重复提交、全局层故障 |
| 本地职责 | 完整控制面、网络、调度与告警 | 全局失联后能否维持既有工作负载 |
| 控制面 | API 多副本;etcd 独立资源、3 或 5 成员 | 故障域、仲裁、磁盘和 N-1 实测容量 |
| 资源池 | 按硬件与隔离要求分池 | 避免过度切分,同时控制争用 |
| 批任务 | 队列准入、配额、受控并发 | 超时回收、抢占与资源不足时的行为 |
| 内容分发 | Cell 级缓存、预热,按需评估 P2P | 冷缓存启动与源站故障 |
| 发布 | 节点池和 Cell 分批推进 | 共享依赖的总变更预算 |
这是一组待验证的设计输入,不是推荐通用配置。节点和 Pod 数在上游规模范围内,也不代表 Service 数、CRD 大小、亲和性规则和变化速率一定满足要求。
etcd 采用 3 还是 5 成员,应按可容忍成员故障及故障域分布决定。3 成员需要 2 个存活,5 成员需要 3 个存活;具体布局要检查任一目标故障域失效后是否仍有多数派,而不是只看总成员数。
11.2 扩容经过多个有界阶段 #
一次扩容可以依次经过:基础设施申请、节点注册、系统组件就绪、镜像预热、开放调度、任务放行。
每个阶段都有独立并发上限和完成条件。节点已经注册,不代表网络、设备、镜像和存储已经可用;应在准备完成后再允许业务调度,避免把大量任务送到半就绪节点。
放量速度依据 API 排队、Lease 延迟、DNS 错误、仓库吞吐、IPAM 和 CSI 队列调整。若下游积压持续增长,停止新一批申请,先消化已有工作。
11.3 容灾预算显式计算 #
四个等容量 Cell 损失一个,计算容量减少 25%。若要求所有现有负载立即转移且不降级,剩余三个 Cell 必须提前具有足够的可用且可匹配资源,而不是只保留少量普通 CPU。
此外,业务副本应事先跨 Cell 或跨所需故障域部署。Cell 失效后再创建全部副本,恢复时间将受镜像、数据和启动链路约束。批任务可以延迟重跑,在线核心服务通常不能依赖同样的恢复策略。
11.4 达到什么条件才继续扩大单集群 #
如果后续出现必须使用大于单 Cell 容量的任务,再比较三种选择:扩大专用 Cell、使用已验证的托管大集群能力,或让任务框架支持跨 Cell 执行。
只有在缓存、无效写入、客户端访问和准入已治理,压测仍显示单集群是必要边界时,才值得承担替换元数据后端或分布式调度的研发成本。
十二、如何证明方案有效 #
12.1 测试覆盖三种运行状态 #
稳态测试验证实际对象规模、Watch 数量、策略数量和长期资源占用;突发测试验证发布、扩容、冷缓存和短任务 churn;故障测试验证控制面副本、存储成员、网络、节点及共享依赖异常后的业务结果。
模拟节点适合测控制面对象与事件压力,但不能证明真实 kubelet、CNI、CSI、GPU 和物理网络的端到端表现。需要将控制面规模测试与真实节点上的关键路径测试结合起来。
12.2 一张最小验收矩阵 #
| 场景 | 施加的负载或故障 | 主要验收结果 |
|---|---|---|
| 目标规模稳态 | 实际 Pod、Service、CRD 和 Watch 分布 | 无持续积压,资源曲线稳定 |
| 批量发布 | 接近设计峰值的创建与删除 | API、调度和启动延迟满足各自目标 |
| 批量节点加入 | 同时带上 DaemonSet、网络和设备初始化 | 关键请求受保护,准备完成后受控放行 |
| 客户端重连 | 多个控制器或 API 副本滚动重启 | 全量同步不造成连续过载 |
| 失去一个 API 副本 | 峰值负载下移除副本 | 其余副本可承接,Watch 重连可收敛 |
| etcd 延迟或成员故障 | 隔离单成员或注入存储延迟 | 仲裁稳定,写入与恢复行为符合预期 |
| 节点 / 机架故障 | 按目标故障规模重建实例 | 业务恢复时间与迁移速率满足要求 |
| DNS / 仓库 / CSI 异常 | 延迟、超时、冷缓存或限流 | 退避生效,无无限重试与连锁故障 |
| 全局层失联 | 暂停全局调度与配置下发 | 本地继续执行,任务不被重复接管 |
| 快照与数据恢复 | 使用真实备份重建隔离环境 | RPO、RTO 及外部资源对齐可验证 |
不要只记录压测器“每秒发出了多少请求”。还要记录成功完成量、错误率、队列长度和端到端延迟;持续增长的队列意味着系统尚未达到可持续吞吐。
12.3 验收目标使用条件化表述 #
目标应写成“什么负载、什么故障、什么时间范围内,达到什么结果”。例如:
在每 Cell 2,500 节点、100,000 个存量 Pod、镜像已预热且无外部存储瓶颈的条件下,失去一个 API Server 副本后,目标提交速率持续运行 30 分钟;关键 API 错误率与 P99 延迟不超过约定阈值,队列在负载下降后于约定时间内清空。
这里的提交速率、错误率和延迟阈值需要由业务 SLO 与实测共同确定,不能引用其他公司的节点规模后直接填入。
12.4 故障排查沿关键路径收敛 #
| 现象 | 第一批证据 | 优先处理方向 |
|---|---|---|
| 所有 API 都慢 | APF 队列、Webhook、etcd、API CPU | 暂停非关键变更,定位共享瓶颈 |
| API 正常但大量 Pending | 配额、调度队列、失败约束、插件耗时 | 区分无资源与决策处理不过来 |
| 已绑定但长时间不启动 | ImagePull、IPAM、卷事件、kubelet | 定位节点侧与外部依赖 |
| 节点大面积 NotReady | Lease 延迟、共享网络、控制面状态 | 先区分真实节点故障与控制路径失效 |
| 扩容越快恢复越慢 | 注册速率、重试、DNS、镜像和 CSI 队列 | 收紧入口,释放关键路径容量 |
| 总体利用率低却一直排队 | 资源形状、GPU 型号、拓扑、配额 | 查碎片与策略约束,重新评估分池 |
万级集群的扩展能力,最终体现在四个方面:控制状态能持续收敛,资源能按业务规则分配,故障能被限制并恢复,变更能分批验证与停止。节点规模应当是这些能力验证后的结果。