- 文档
- 教程
- 云原生
【免费下载链接】docs
User documentation for Knative components.
Knative Serving 的缩零(Scale to Zero)是其 Serverless 能力的核心特性之一:当 Revision 没有流量时,KPA 自动缩容器会将其副本数降为 0,使集群不再为闲置应用占用资源;流量再次到来时又能自动从 0 恢复。本篇围绕 Knative 官方文档中 Scale to Zero 的三个配置项展开——enable-scale-to-zero(全局开关)、scale-to-zero-grace-period(缩零宽限期)、scale-to-zero-pod-retention-period(最后一个 Pod 的最小保留时长),完整给出 ConfigMap、Operator、Revision 注解三种配置方式的示例,并结合仓库中的示例应用与观测手段,帮助你验证缩零行为、排查缩零期间的请求丢失问题。
适用前提:缩零只由 KPA 支持,且只能全局配置
在配置之前,必须先明确文档中的关键前提约束:
Scale to zero can only be enabled if you are using the KnativePodAutoscaler (KPA), and can only be configured globally.(缩零只能在使用 Knative Pod Autoscaler(KPA)时启用,且只能全局配置。)
具体来说:
- 只有 KPA 支持缩零。Knative Serving 内置两个 Autoscaler 实现——KPA(Knative Pod Autoscaler)和 HPA(委托给 Kubernetes 的 Horizontal Pod Autoscaler)。根据 Supported Autoscaler types 的说明:KPA 是 Knative Serving 核心的一部分,安装后默认启用,支持缩零,但不支持 CPU 类指标扩缩;HPA 则不支持缩零,但支持 CPU 指标,且需要在安装 Knative Serving 之后单独安装。
- 缩零没有 per-revision 开关。
enable-scale-to-zero只有全局 key,无法像min-scale那样按 Revision 单独关闭/开启。
Autoscaler 类型本身通过class注解与全局 key 切换:
- Global key:
pod-autoscaler-class - Per-revision annotation key:
autoscaling.knative.dev/class - Possible values:
"kpa.autoscaling.knative.dev"或"hpa.autoscaling.knative.dev" - Default:
"kpa.autoscaling.knative.dev"
# Per Revision:显式指定使用 KPA(默认值) apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-go namespace: default spec: template: metadata: annotations: autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" spec: containers: - image: ghcr.io/knative/helloworld-go:latest全局开关的优先级规则见 Supported Autoscaler types 一节的描述:未指定 per-revision 设置时使用全局设置;两者同时存在时 per-revision 设置覆盖全局设置。但如前所述,缩零开关本身不属于可覆盖的全局项。
开启或禁用缩零:enable-scale-to-zero
该值控制 Knative 是否允许副本数缩到 0(true)或在缩容到 1 个副本时停止(false):
- Global key:
enable-scale-to-zero - Per-revision annotation key:无(不支持 per-revision 设置)
- Possible values:boolean
- Default:
true
从 Supported Autoscaler types 给出的默认config-autoscalerConfigMap 可以看到该 key 的出厂默认值(完整默认值列表中还包含scale-to-zero-grace-period: "30s"、scale-to-zero-pod-retention-period: "0s"、stable-window: "60s"等本文后续涉及的值):
apiVersion: v1 kind: ConfigMap metadata: name: config-autoscaler namespace: knative-serving data: container-concurrency-target-default: "100" container-concurrency-target-percentage: "0.7" enable-scale-to-zero: "true" max-scale-up-rate: "1000" max-scale-down-rate: "2" panic-window-percentage: "10" panic-threshold-percentage: "200" scale-to-zero-grace-period: "30s" scale-to-zero-pod-retention-period: "0s" stable-window: "60s" target-burst-capacity: "200" requests-per-second-target-default: "200"通过 ConfigMap 配置(全局)
将enable-scale-to-zero设为false即可全局禁用缩零:
apiVersion: v1 kind: ConfigMap metadata: name: config-autoscaler namespace: knative-serving data: enable-scale-to-zero: "false"通过 Operator(KnativeServing CR)配置(全局)
如果 Knative Serving 是通过 Operator 安装的,全局配置项也可以直接写在KnativeServing自定义资源的spec.config.autoscaler中,由 Operator 将其转化为config-autoscaler配置。Operator 对 Serving CR 的配置方式参见 配置 KnativeServing CR:
apiVersion: operator.knative.dev/v1alpha1 kind: KnativeServing metadata: name: knative-serving spec: config: autoscaler: enable-scale-to-zero: "false"仓库中的真实用例:bookstore 示例应用禁用缩零
在仓库的 bookstore 示例解决方案中,就存在一份专门禁用缩零的 ConfigMap,其内容正是上面的最小配置,并在文件注释中说明用途——“当没有请求时将 Pod 数量缩到 0”:
# This is a ConfigMap that disables the scale-to-zero feature in Knative Serving. # The scale-to-zero feature scales down the number of pods to zero when there are no requests. apiVersion: v1 kind: ConfigMap metadata: name: config-autoscaler namespace: knative-serving data: enable-scale-to-zero: "false"见 100-scale-to-zero-disable.yaml。
与 min-scale 的联动关系
缩零开关并非孤立生效,它与最小副本数(scale bounds)存在联动:根据 Configuring scale bounds 的说明,min-scale的默认值是——当缩零启用且 class 为 KPA 时为0,否则为1。也就是说:
- 默认(
enable-scale-to-zero: "true")时,未显式配置min-scale的 Revision 下限就是 0,流量停止后最终会缩到 0; - 若全局禁用缩零,未配置
min-scale的 Revision 下限变为 1,副本数缩到 1 后停止; - 若只想让个别 Revision 不缩零,不需要动全局开关,直接按 Revision 设置
autoscaling.knative.dev/min-scale: "1"即可(这是 per-revision 层面实现“不缩零”的唯一途径)。
缩零宽限期:scale-to-zero-grace-period
该设置指定系统在移除最后一个副本之前,内部等待 scale-from-zero 机制(activator 接管、网络编程完成等)就绪的时间上限:
- Global key:
scale-to-zero-grace-period - Per-revision annotation key:无
- Possible values:Duration
- Default:
30s
文档特别给出两点重要澄清,理解它避免了常见误用:
- 它只控制内部网络编程允许花费的时间。官方警告称:该值只有在你的 Revision 缩到 0 副本期间观察到请求被丢弃(requests being dropped)时,才应该调整它。
- 它不控制最后一个副本在流量停止后保留多久。它也不保证副本真的会保留整个宽限期时长。真正决定“最后一个副本何时被移除”的是
stable-window:根据 KPA 专属配置 的说明,缩到 0 时,只有当 Revision 在整个 stable window 时长内都没有任何流量,最后一个副本才会被移除(默认60s)。
配置示例
# 全局(ConfigMap):宽限期放宽到 40 秒 apiVersion: v1 kind: ConfigMap metadata: name: config-autoscaler namespace: knative-serving data: scale-to-zero-grace-period: "40s"# 全局(Operator) apiVersion: operator.knative.dev/v1alpha1 kind: KnativeServing metadata: name: knative-serving spec: config: autoscaler: scale-to-zero-grace-period: "40s"最后一个 Pod 的最小保留时长:scale-to-zero-pod-retention-period
scale-to-zero-pod-retention-period决定在 Autoscaler 决定把 Pod 缩到 0 之后,最后一个 Pod最少保留活跃多长时间。文档中明确指出它与宽限期是一对“下界/上界”关系:
- retention period:决定最后一个 Pod 至少活跃多久(最小值);
- grace period:决定最后一个 Pod 最多活跃多久(最大值)。
参数说明:
- Global key:
scale-to-zero-pod-retention-period - Per-revision annotation key:
autoscaling.knative.dev/scale-to-zero-pod-retention-period(三个参数中唯一支持 per-revision 注解的) - Possible values:非负 duration 字符串
- Default:
0s
按 Revision 配置(注解方式)
在 Service 的 revision template 上添加注解,使之后创建的每个 Revision 都继承该设置:
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-go namespace: default spec: template: metadata: annotations: autoscaling.knative.dev/scale-to-zero-pod-retention-period: "1m5s" spec: containers: - image: ghcr.io/knative/helloworld-go:latest全局配置(ConfigMap 与 Operator)
# 全局(ConfigMap) apiVersion: v1 kind: ConfigMap metadata: name: config-autoscaler namespace: knative-serving data: scale-to-zero-pod-retention-period: "42s"# 全局(Operator) apiVersion: operator.knative.dev/v1alpha1 kind: KnativeServing metadata: name: knative-serving spec: config: autoscaler: scale-to-zero-pod-retention-period: "42s"注意文档中反复强调的一点:如果使用 Service 或 Configuration 创建 Revision,注解必须写在revision template的metadata.annotations下,这样修改才会应用到之后生成的每个 Revision;只写在单个 Revision 顶层 metadata 上不会传播到其他 Revision。
验证缩零行为:从观测到压测
理解参数只是第一步,真正落地时需要能观察和验证缩零过程。仓库提供了两种可操作的验证路径。
用 kubectl watch 观察副本归零与恢复
入门教程 first-autoscale.md 展示了最直接的观察方式:对 Service 发起请求后停止流量,然后watchPod 列表:
kubectl get pod -l serving.knative.dev/service=hello -w预期会看到 Pod 从Running经过Terminating逐步消失(教程说明“最多可能需要约 2 分钟”,再次访问会重置计时器);之后再次访问 URL,可以看到 Pod 从Pending、ContainerCreating到Running的从零重建过程。这个 2 分钟量级的耗时与默认stable-window: "60s"(无流量判定窗口)加上宽限期等内部机制的叠加是一致的。
用 autoscale-go 示例应用做受控压测
Go Autoscale Sample App 是验证缩容/扩缩容行为的完整实验环境。其部署文件将目标并发度设为每 Pod 10 个 in-flight 请求(见 service.yaml):
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: autoscale-go namespace: default spec: template: metadata: annotations: # Target 10 in-flight-requests per pod. autoscaling.knative.dev/target: "10" spec: containers: - image: ghcr.io/knative/autoscale-go:latest示例应用本身是一个可通过查询参数控制资源消耗的 Go 程序(见 autoscale.go):?sleep=100让请求挂起约 100ms 以维持并发,?prime=10000消耗 CPU,?bloat=5分配内存。典型压测流程是发送 30 秒、50 并发在途请求的负载,然后观察 Pod 数量:
kubectl apply -f docs/versioned/serving/autoscaling/autoscale-go/service.yaml # 维持 50 个在途请求 30 秒,结束后查看 Pod hey -z 30s -c 50 \ "http://autoscale-go.default.1.2.3.4.sslip.io?sleep=100&prime=10000&bloat=5" \ && kubectl get pods按默认目标并发(Knative 默认 target concurrency 为 100,本示例覆盖为 10)计算:50 并发请求 ÷ 目标 10 = 5 个 Pod,与示例文档中的分析一致。上方文章头部的监控面板截图即来自该示例应用,展示了负载期间 Revision Pod 数量(Actual/Requested)上升、负载停止后按max-scale-down-rate约束逐级回落的过程,以及对应的 CPU 与内存用量曲线——这正是“缩零前如何一步步降副本”的直观形态。
清理实验环境:
kubectl delete -f docs/versioned/serving/autoscaling/autoscale-go/service.yaml参数总览与配置方式速查
将三个参数的属性汇总如下,便于检索和对照(全局配置的两种载体:knative-serving/config-autoscalerConfigMap,或KnativeServingCR 的spec.config.autoscaler):
| 参数(Global key) | 作用 | Per-revision 注解 key | 类型 | 默认值 | 配置范围 |
|---|---|---|---|---|---|
enable-scale-to-zero | 是否允许副本缩到 0(false 时缩到 1 停止) | 无 | boolean | true | 仅全局 |
scale-to-zero-grace-period | 移除最后一个副本前,系统等待 scale-from-zero 机制就绪的上限时间 | 无 | Duration | 30s | 仅全局 |
scale-to-zero-pod-retention-period | Autoscaler 决定缩 0 后,最后一个 Pod 最少保留活跃的时间 | autoscaling.knative.dev/scale-to-zero-pod-retention-period | 非负 duration | 0s | 全局 + 按 Revision |
与之相关、经常需要联动的其他 KPA 参数(详细语义见各自文档):
stable-window(KPA 专属配置):最后一个副本只有在整个稳定窗口内无流量后才移除,默认60s,范围6s~1h;min-scale/autoscaling.knative.dev/min-scale(Configuring scale bounds):KPA 且缩零启用时默认0,是 per-revision 层面避免缩零的手段;scale-down-delay/autoscaling.knative.dev/scale-down-delay:要求低并发持续一段时间后才执行缩容决策,可用于避免间歇性流量反复触发冷启动,默认0s,仅支持默认 KPA class;pod-autoscaler-class/autoscaling.knative.dev/class(Supported Autoscaler types):KPA 与 HPA 的切换开关,HPA 路径下缩零不可用。
小结与调优建议
- 缩零是 KPA 的全局特性:
enable-scale-to-zero默认true且没有 per-revision 覆盖;需要“个别服务不缩零”时,用 per-revision 的autoscaling.knative.dev/min-scale: "1"或scale-down-delay注解,而不是动全局开关。 - 三个时间参数各管一段:
stable-window决定“何时判定可以缩零”,scale-to-zero-grace-period决定“移除最后一个副本前等待内部机制就绪的上限”,scale-to-zero-pod-retention-period决定“决定缩零后最后一个副本至少保留多久”。文档明确警告:grace period 只有在缩零期间出现请求丢失时才应调整,不要把它当作控制副本保留时长的工具。 - 配置载体二选一:YAML 安装(
kubectl applyConfigMap)或 Operator 安装(KnativeServingCR 的spec.config.autoscaler),两种方式最终效果等价,选择与集群安装方式一致的载体即可。 - 用工具验证:
kubectl get pod -l serving.knative.dev/service=<name> -w观察归零/重建,或用 autoscale-go 示例 以可控并发压测并结合Revision Pod Counts监控面板,确认扩缩容曲线符合预期后再调参。
- 文档
- 教程
- 云原生
【免费下载链接】docs
User documentation for Knative components.
相关推荐
Knative Serving 自动扩缩容边界配置实战:min-scale、max-scale 与 initial-scale 等核心参数详解
Knative Serving 自动扩缩容边界配置实战:min scale、max scale 与 initial scale 等核心参数详解 Knative
文档教程云原生KEDA缩容到零实战:如何用Scale-to-Zero彻底消灭空闲Pod,把云账单打到零
KEDA缩容到零实战:如何用Scale to Zero彻底消灭空闲Pod,把云账单打到零 KEDA 缩容到零(Scale to Zero)是事件驱动自动扩缩容的
云原生容器编排BentoML BentoCloud 弹性伸缩实战:Concurrency、Autoscaling、Scale-to-Zero 与多区域 Gateways
BentoML BentoCloud 弹性伸缩实战:Concurrency、Autoscaling、Scale to Zero 与多区域 Gateways 本文
模型推理服务人工智能后端大模型MLOpsLLMOps
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考