XMBSMDSJ

2026

< Back to index

Knative Serving 和云成本

笔者有多套 LLMOps 平台,苦于成百上千的插件/沙箱,以及每个月 3000 美元的云服务成本。

Knative Serving 的 Scale to Zero 特性是云成本控制中十分有效的手段。

Scale to Zero 的难点

当我们说弹性伸缩,往往是 1-N 的伸缩,通常基于一些指标,比如 CPU 使用率、内存使用率、请求量等。

而 Scale to Zero 则是 0-1 的伸缩,这在技术上更加复杂,因为需要处理冷启动、资源预热等问题,因此一定需要网络层的介入。

HPA 的 scale to zero

k8s 最新版本的 HPA 已经支持 scale to zero,然而,它更适用于一些批处理等任务。当一个 web 服务被 HPA scale to zero,此时如果有请求到达,客户端只能得到一个服务不可用的报错。

Knative Serving 的架构

API 抽象

资源层级:Service → Configuration + Route → Revision → PodAutoscaler → Deployment/Pod

ksvc 控制器行为

创建/更新 ksvc 时,Service Reconciler (pkg/reconciler/service/service.go) 执行:

  1. 调和 Configuration:不存在则创建;已存在则对比 Spec/Labels/Annotations,有 diff 则 Update。
  2. 等待 Configuration 就绪:若 Configuration 未 reconcile 完(Generation != ObservedGeneration),标记 ConfigurationNotReconciled 并等待。就绪后将 Configuration 状态传播到 Service。
  3. 调和 Route:不存在则创建;已存在则对比期望状态,有 diff 则 Update。Route Spec 中未指定 RevisionName 的 TrafficTarget 自动填充 Configuration 名。
  4. 传播状态:将 Route 的 URL、Traffic、Conditions 回写到 Service Status。若 Route 实际流量分配与期望不一致,标记 RouteNotYetReady

整个过程是纯声明式的:Service 只负责编排 Configuration 和 Route,不直接操作 Pod。Revision、PA、Deployment 的管理由各自下游控制器完成。

数据面架构

在数据面,serving 通过以下组件实现请求的路由和处理:

数据流

正常(有 Pod): Client → Ingress → Queue Proxy → 用户容器
缩零后首请求:  Client → Ingress → Activator → (触发扩容,等待 Pod Ready) → Queue Proxy → 用户容器

Activator 在 Pod 充足且 ExcessBurstCapacity > 0 后会被摘出请求路径,流量直连 Pod。

可插拔的网络层

KIngress:网关适配

Route 控制器创建 KIngress CRD(声明域名规则 + 流量百分比拆分),由 adapter 控制器 翻译为具体网关配置:

Knative 只写 adapter 控制器,不写网关本身。切换只改 config-networkingress-class

SKS:Activator 出入开关

每个 Revision 有一个无 selector 的 public Service,其 Endpoints 由 SKS 控制器按模式手动写入:

另有 private Service(有 selector)始终指向 Pod,供 Autoscaler 抓指标和 Activator 发现后端。

Serve:  Gateway → public-svc (Pod:8012) → Queue Proxy → 用户容器
Proxy:  Gateway → public-svc (Activator) → Activator → Pod:8012 → Queue Proxy → 用户容器

网关对 Endpoints 切换完全透明,只管按 Service 转发。