ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Knative Serving 缩零(Scale to Zero)配置详解:enable-scale-to-zero、宽限期与 Pod 保留期

Knative Serving 缩零(Scale to Zero)配置详解:enable-scale-to-zero、宽限期与 Pod 保留期
  • 文档
  • 教程
  • 云原生

【免费下载链接】docs

User documentation for Knative components.

项目地址:https://gitcode.com/gh_mirrors/docs1/docs
点击查看免费下载

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)时启用,且只能全局配置。)

具体来说:

  1. 只有 KPA 支持缩零。Knative Serving 内置两个 Autoscaler 实现——KPA(Knative Pod Autoscaler)和 HPA(委托给 Kubernetes 的 Horizontal Pod Autoscaler)。根据 Supported Autoscaler types 的说明:KPA 是 Knative Serving 核心的一部分,安装后默认启用,支持缩零,但不支持 CPU 类指标扩缩;HPA 则不支持缩零,但支持 CPU 指标,且需要在安装 Knative Serving 之后单独安装。
  2. 缩零没有 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

文档特别给出两点重要澄清,理解它避免了常见误用:

  1. 它只控制内部网络编程允许花费的时间。官方警告称:该值只有在你的 Revision 缩到 0 副本期间观察到请求被丢弃(requests being dropped)时,才应该调整它。
  2. 它不控制最后一个副本在流量停止后保留多久。它也不保证副本真的会保留整个宽限期时长。真正决定“最后一个副本何时被移除”的是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 停止)无booleantrue仅全局
scale-to-zero-grace-period移除最后一个副本前,系统等待 scale-from-zero 机制就绪的上限时间无Duration30s仅全局
scale-to-zero-pod-retention-periodAutoscaler 决定缩 0 后,最后一个 Pod 最少保留活跃的时间autoscaling.knative.dev/scale-to-zero-pod-retention-period非负 duration0s全局 + 按 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 路径下缩零不可用。

小结与调优建议

  1. 缩零是 KPA 的全局特性:enable-scale-to-zero默认true且没有 per-revision 覆盖;需要“个别服务不缩零”时,用 per-revision 的autoscaling.knative.dev/min-scale: "1"或scale-down-delay注解,而不是动全局开关。
  2. 三个时间参数各管一段:stable-window决定“何时判定可以缩零”,scale-to-zero-grace-period决定“移除最后一个副本前等待内部机制就绪的上限”,scale-to-zero-pod-retention-period决定“决定缩零后最后一个副本至少保留多久”。文档明确警告:grace period 只有在缩零期间出现请求丢失时才应调整,不要把它当作控制副本保留时长的工具。
  3. 配置载体二选一:YAML 安装(kubectl applyConfigMap)或 Operator 安装(KnativeServingCR 的spec.config.autoscaler),两种方式最终效果等价,选择与集群安装方式一致的载体即可。
  4. 用工具验证:kubectl get pod -l serving.knative.dev/service=<name> -w观察归零/重建,或用 autoscale-go 示例 以可控并发压测并结合Revision Pod Counts监控面板,确认扩缩容曲线符合预期后再调参。
  • 文档
  • 教程
  • 云原生

【免费下载链接】docs

User documentation for Knative components.

项目地址:https://gitcode.com/gh_mirrors/docs1/docs
点击查看免费下载

相关推荐

上一篇:仓颉社区代码合入标准与 Committer 治理机制全解析
下一篇:3分钟把NCM转成MP3:ncmdump拖拽上手指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进