思路:基于升级域与委托就绪的多机推理集群高可用升级¶
概述¶
本思路旨在解决 Kubernetes 节点升级过程中,多机推理工作负载(如 LWS、Ray 等)的通用、解耦的高可用性问题,而无需引入自定义 Webhook 或沉重的 AI 特定的调度器。
问题陈述¶
在传统的 Kubernetes 集群升级中,控制面(如 Node Drain)通常是工作负载无关(Workload Agnostic)的,且基于 Pod 维度进行优雅终止。然而,大模型多机推理(Multi-Host Inference)是典型的紧耦合(Gang)工作负载,要求组内所有 Pod “同生共死”。
这导致了以下核心矛盾:
- 原生 PDB 的盲区:原生的 PodDisruptionBudget 只能按 Pod 数量控制中断,无法理解“只要死一个 Worker,整组推理就瘫痪”的组级语义。
- 重复中断与容量雪崩:逐个驱逐节点会导致同一个组被反复打碎重建;随机并发驱逐则可能同时击碎多个组,导致服务容量雪崩。
- 平台与业务的强耦合:为了解决上述问题,业界常采用自定义 Webhook 或引入 Kueue 等 AI 调度器,但这往往需要平台去理解上层业务的特定 Label(如 LWS 的 group-index),破坏了平台与应用解耦的原则。
前提假设¶
本思路的有效性基于以下工程前提和假设:
- 资源受限或成本敏感:集群硬件资源是固定的,或者团队不愿意为了升级而拉起大规模的蓝绿节点池(Blue-Green Pool)造成资源浪费。
- 必须进行节点驱逐(Drain):集群节点和 OS 的升级需要进行节点驱逐。虽然业界在探索“免驱逐(Drainless)”的热升级技术,但它们并不原生支持,且不能适用于所有场景(例如涉及数据面 CVE 漏洞修复或内核更新时,必须重启节点)。
- 业务必须容忍容量降级:由前两条假设可以推导出,在升级期间我们必须以时间换空间——即在升级窗口内主动降低集群的总服务容量(Capacity),同时维持最低限度的高可用(HA)。上层应用必须接受这一阶段性的容量降级。
- 原生组级 PDB 缺失:Kubernetes 目前还没有原生支持 PodGroup 维度的驱逐和 Disruption Budget。虽然在前沿提案(如 KEP-4563: Eviction Request API)中已经开始讨论未来对上层 Workload 的支持,但目前仍处于早期阶段。本思路的目标是在仅利用现有 Kubernetes 原生机制的前提下,解决组级高可用升级的问题。
核心概念¶
本思路利用 Kubernetes 的原生基元与机制(如拓扑标签 Topology Labels、Pod 就绪探针 Readiness Probe 和 PodDisruptionBudget),并引入常见的 “升级域”(Upgrade Domain, UD) 拓扑概念。通过建立一个契约,让指定的 Pod(例如 Leader)聚合整个组的健康状态,我们可以使用标准的 PDB 来保护滚动升级期间组的可用性。
三层契约¶
为了接入平台并享受自动、安全的升级,工作负载必须遵守以下契约。注意:该契约仅适用于在升级过程中对可用性(Uptime)有强要求的工作负载。如果业务可以在维护窗口(Maintenance Window)内完全下线,则无需遵守此契约。
- 拓扑要求(跨 UD 打散):工作负载必须使用
topologySpreadConstraints或反亲和性将不同的推理组(副本)打散到不同的升级域(UD)中。- 以 LWS 为例:
- 组内强亲和(Pack):配置 Worker Pod 与其对应的 Leader Pod 具有强亲和性(
podAffinity),确保同一个推理组的所有 Pod 都被包裹在同一个升级域内,避免组内通信被跨域升级切断。 - 组间反亲和(Spread):配置不同推理组的 Leader Pod 之间基于升级域的标签进行打散(使用
topologySpreadConstraints或podAntiAffinity),确保不同的推理组分布在不同的升级域中,从而在升级某个 UD 时,最多只会破坏一个组。
- 组内强亲和(Pack):配置 Worker Pod 与其对应的 Leader Pod 具有强亲和性(
- 以 LWS 为例:
- 委托就绪(健康聚合):工作负载必须指定一个 Pod(例如 LWS Leader),其
ReadinessProbe对组内的所有成员执行健康检查。如果任何成员失败或被驱逐,该代表 Pod 将变为Unready。 - 代表 Pod 的 PDB:针对代表 Pod 定义一个 PDB。由于该 Pod 的就绪状态反映了组的健康状况,因此 PDB 实际上成为了可用组数量的预算。
升级期间的工作流¶
平台以 升级域 级别执行升级。为了确保 PDB 的拦截机制真正生效,升级控制面在驱逐一个 UD 内的节点时,必须遵循以下精细化逻辑:
- 区分 Pod 类型:扫描目标升级域(如
UD 1)内所有的 Pod,将其分为“受 PDB 保护的 Pod”(如 Leader)和“无 PDB 保护的 Pod”(如 Worker)。 - 优先驱逐受 PDB 保护的 Pod:必须首先向所有受 PDB 保护的 Pod 发起驱逐请求。这是因为无 PDB 保护的 Pod(Worker)一旦先被驱逐,会直接破坏组的完整性而绕过 PDB 的拦截。只有先驱逐受保护的 Pod,才能在触发 PDB 违规时被 Eviction API 正确拦截。
- 再快速驱逐其余 Pod:只有当该 UD 内所有受 PDB 保护的 Pod 都被成功驱逐后,升级控制面才可以快速驱逐该 UD 内剩余的无 PDB 保护的 Pod。
- 跨域拦截:如果存量可用组数不足,步骤 2 会被 PDB 阻塞,升级控制面将暂停推进,直到之前的组在其他 UD 的新节点上恢复并再次变为
Ready。
总结与评估¶
本思路通过组合 Kubernetes 原生的拓扑标签、就绪探针和 PDB,在不破坏平台与应用解耦的前提下,实现了多机推理工作负载的通用高可用升级。该方案的优势在于其通用性与云原生性,无需为特定的 AI 框架定制控制器。但在落地时,升级控制面必须注意处理状态传播的延迟,且应用方必须严格将组健康检查置于 ReadinessProbe 中以防误杀。总体而言,这是一个遵循 Kubernetes 哲学,适合资源受限环境的通用高可用升级方案。