一句话结论
Uber 推出 ServiceScale 控制器,通过解耦扩缩容意图与执行,支持多编排器安全管理同一批 Kubernetes 工作负载,实现无需预留闲置容量的区域故障转移。
关键要点
- Uber 引入自定义资源定义 ServiceScale 和服务扩缩容控制器(SSC),允许多个编排器安全地管理同一组 Kubernetes 工作负载的扩缩容,且无需引入外部数据库、独立协调服务或控制平面。
- 该方案将扩缩容意图直接物化在 Kubernetes 中,稳态和临时故障转移信息都保存在 CRD 规范中,故障恢复时无需从日志中重建状态,便于排查与调试。
- 针对 Informer 缓存过期问题,Uber 实现了“读己所写”一致性防护机制:控制器更新下游资源时,会把当前资源版本号作为注解打上,在上报状态前先校验本地缓存至少已读到该版本。
- 多写入者系统下 UDC 和 SSC 同时更新同一资源时会产生 ReplicaSet 元数据与规范漂移问题,Uber 在 UDC 中加入全集群可观测能力检测不一致并构建自动修复程序。
- 该方案支持原生 Kubernetes Deployment 和 OpenKruise CloneSet,整个方案上线耗时一年,通过预发布环境、金丝雀发布及基于 KubeKind 的集成测试,全程未造成客户可感知的中断。
背景与事实
Uber 的容器平台团队管理着分布在数据中心和云厂商(包括 Oracle 和谷歌)的 100 多个计算集群,运行着约 4000 个服务,使用 300 万核 CPU,每天启动 150 万个 Pod。该团队的内部平台叫作 Up,作为 Kubernetes 集群群联邦层。服务所有者使用 Up 部署构建版本并设置扩缩容预期,而 Uber 部署控制器(UDC)会将这些意图调和为 Kubernetes 原语。
这一改变的动机来自 Uber 处理区域故障转移方式的变革。Uber 在不同区域运行双活数据中心,当发生故障时,流量会被重定向到幸存区域,该区域需要足够的空闲计算资源来应对增加的负载。过去,Uber 在所有数据中心都保留了预留的空闲容量,工程师们希望改为复用低优先级工作负载的容量,在故障发生时缩容低优先级工作负载,扩容高优先级工作负载。这就产生了新的扩缩容意图来源,Up 和 UDC 仍负责维护服务常规期望状态,但故障转移编排器也需要参与扩缩容决策。
面对新需求,工程师们考虑过用故障转移逻辑扩展 UDC,但最终决定不这么做。UDC 已经处于服务生命周期操作的关键路径上,添加故障转移特定行为会增加这个控制器的复杂性。高级软件工程师 Egor Grishechko 和 Srikar Paruchuru 指出,“故障转移处理一旦出现回归问题,不会只停留在故障转移层面”,而可能影响整个集群的正常部署。因此,团队引入了新的自定义资源定义 ServiceScale 和新的服务扩缩容控制器(SSC),每个编排器都可以通过 ServiceScale 表达自己的扩缩容意愿,SSC 将组合后的意图调和为 Kubernetes 对象。Grishechko 和 Paruchuru 解释说,“我们不想额外引入外部数据库、独立协调服务或是控制平面,否则在故障应急场景下,调试难度会大幅上升。”
影响分析
对中文开发者与从业者而言,Uber 的实践提供了生产环境中多编排器 Kubernetes 集群管理的可复用方法论。分析判断认为,该方案对采用多集群联邦架构或需要频繁处理区域故障转移的国内企业具有重要参考价值。其核心启示在于:当多个控制器需要协调管理同一批工作负载时,解耦意图与执行、将状态持久化到 Kubernetes 原生的 CRD 中,能显著降低故障场景下的调试复杂度。此外,Uber 针对 Informer 缓存过期和“读己所写”一致性问题的解决方案,以及处理多写入者并发竞态的可观测与自动修复机制,为构建高可靠性的云原生控制平面提供了具体的工程实践范本。
适用边界
该结论主要适用于已具备多区域双活数据中心架构、且运行大规模 Kubernetes 集群群(联邦层)的超大规模互联网平台场景。对于仅运行单区域集群、或对故障转移有快速恢复需求但无法承受长期方案迁移成本的中小规模系统,直接复用该多编排器解耦架构可能过于复杂,需权衡引入额外控制器带来的运维成本。
孤本观察
判断 Uber 方案的核心价值并非单纯的技术创新,而在于将复杂的分布式并发控制问题收敛到 Kubernetes 原生资源模型中,通过“意图物化”换取故障时的可观测性与可恢复性,这代表了云原生控制平面演进中“状态即代码”工程哲学的典型落地。





常见问题
ServiceScale 控制器方案支持哪些 Kubernetes 工作负载类型?
该方案支持原生 Kubernetes Deployment 和 OpenKruise CloneSet。
Uber 管理的大规模集群中每天启动的 Pod 数量及使用的 CPU 核数是多少?
每天启动 150 万个 Pod,使用 300 万核 CPU。
针对 Informer 缓存过期问题,Uber 采用了何种一致性防护机制?
实现“读己所写”机制,更新资源时打上版本号注解,上报状态前校验本地缓存至少已读到该版本。
为什么 Uber 选择新建 SSC 控制器而不是扩展现有的 UDC 控制器?
UDC 处于服务生命周期关键路径,添加故障转移逻辑会增加复杂性,且回归问题可能影响整个集群部署。
该多编排器解耦架构主要适用于哪些企业场景?
适用于具备多区域双活数据中心架构、运行大规模 Kubernetes 集群群的超大规模互联网平台。
来源:InfoQ 中文 AI