只有当扩缩容指标能在网关饱和前足够早地预示压力,让新增容量及时就绪时,弹性扩展才真正有效。CPU 可以作为指标,但它并不是完整的容量模型:连接数、请求成本、事件循环延迟、上游延迟和下游限制都可能更早成为瓶颈。
因此,安全的扩缩容设计需要同时具备需求或饱和度指标、最低热容量、经过测试的启动时间、准入控制和保守的缩容策略。自动扩缩容器只能改变副本数,无法凭空增加数据库连接、第三方配额、区域 IP 地址或上游容量。
核心要点
- 先通过负载测试定义一个容量单位,再选择扩缩容目标。
- 保留足够的就绪副本,以覆盖启动延迟、节点故障和正常流量波动。
- 使用具有前瞻性的需求或饱和度指标;延迟和错误率应作为护栏,而不是盲目扩容的指令。
- 使用 Kubernetes HPA 的 CPU 利用率前,先正确配置资源请求值。
- 延缓缩容、排空连接,并在终止网关 Pod 前确认它已退出端点选择。
- 测试指标缺失、冷启动、下游饱和、突发流量和故障恢复。
先确定容量边界
负载测试应采用有代表性的流量组合,而不是只压测一个轻量接口。记录服务级目标开始失守的位置,并找出最先受限的资源。
| 维度 | 需要回答的问题 | 对扩缩容的影响 |
|---|---|---|
| 请求速率 | 一个就绪副本能处理多少符合测试组合的请求? | 将预测需求转换为基础副本数 |
| 并发量 | 多少活跃 HTTP、WebSocket、gRPC 或流式会话是安全的? | 可能在 CPU 升高前触发扩容 |
| 请求成本 | 哪些路由会执行 TLS、认证、转换或大请求体处理? | 单一全局 RPS 目标会掩盖高成本流量 |
| 启动时间 | 从调度到就绪,在拉取镜像和加载配置条件下需要多久? | 决定所需余量和反应时间 |
| 依赖预算 | 后端能够接受多少连接或请求? | 限定扩容实际能带来的收益 |
| 故障余量 | Pod、节点或可用区故障后还剩多少容量? | 决定 minReplicas 和部署分布要求 |
不要发布一个适用于所有环境的 RPS 数字。测试结果只对当时的硬件、配置、插件组合、协议、负载、上游和延迟目标有效。
构建闭环扩缩容系统
1flowchart LR
2 T[客户端流量] --> G[已就绪的网关副本]
3 G --> U[上游容量]
4 G --> M[网关与平台指标]
5 U --> M
6 M --> A[指标适配器与自动扩缩容器]
7 A -->|扩容或缩容| G
8 P[策略:边界、限流、稳定窗口] --> A
9 O[SLO 与成本审查] --> P请求路径是“客户端 → 网关 → 上游”。指标流向适配器和自动扩缩容器,它们只是观测结果,不是授权或路由决策。策略负责人负责设定边界并审查运行结果。
Apache APISIX 3.19.0 的 prometheus 插件会暴露当前客户端连接数、HTTP 状态计数,以及请求、上游和 APISIX 延迟直方图等指标。这些数据可用于容量分析,但只有 Prometheus Adapter 或其他指标管道通过 Kubernetes 指标 API 发布相应指标后,它们才会成为 Kubernetes 自定义指标。
按故障模式选择指标
| 指标 | 优点 | 需要防范的问题 |
|---|---|---|
| CPU 利用率 | 易于获取,适合计算密集型插件 | 依赖正确的 CPU 请求值,也可能晚于网络或连接压力 |
| 活跃请求或连接 | 能提前反映长连接或慢请求压力 | 不同协议中的一个连接并不代表相同工作量 |
| 每个就绪副本的请求数 | 适合流量组合稳定的场景 | 无法反映路由成本和下游瓶颈 |
| 队列等待时间或事件循环延迟 | 直接显示等待中的工作 | 需要可靠埋点和经过测试的目标值 |
| 长尾延迟和错误率 | 直接保护用户目标 | 高值可能来自上游,扩容网关反而会放大故障 |
可以用延迟和错误指标来决定是继续、限流还是停止发布。如果数据库已经饱和,增加网关副本和连接只会让事故更严重。
把 HPA 配置成明确的策略
Kubernetes autoscaling/v2 支持资源、Pod、对象和外部指标,也支持分别设置扩容与缩容行为。使用 CPU 利用率时,HPA 会以容器 CPU 请求值为基准计算利用率,因此缺失或不切实际的请求值会让目标失真。
下面的示例具备可运行配置的结构,但仍需替换集群相关数值。它假设指标适配器已经将 gateway_inflight_requests 发布为每个 Pod 的平均自定义指标;这不是 APISIX 原生指标名称。
1apiVersion: autoscaling/v2
2kind: HorizontalPodAutoscaler
3metadata:
4 name: apisix-gateway
5spec:
6 scaleTargetRef:
7 apiVersion: apps/v1
8 kind: Deployment
9 name: apisix-gateway
10 minReplicas: 4
11 maxReplicas: 20
12 metrics:
13 - type: Resource
14 resource:
15 name: cpu
16 target:
17 type: Utilization
18 averageUtilization: 60
19 - type: Pods
20 pods:
21 metric:
22 name: gateway_inflight_requests
23 target:
24 type: AverageValue
25 averageValue: "200"
26 behavior:
27 scaleUp:
28 stabilizationWindowSeconds: 0
29 policies:
30 - type: Percent
31 value: 100
32 periodSeconds: 60
33 scaleDown:
34 stabilizationWindowSeconds: 300
35 policies:
36 - type: Percent
37 value: 25
38 periodSeconds: 60这些数值只是示例,不是推荐值。配置多个指标时,HPA 会分别计算期望副本数,并采用其中最大的值。Kubernetes 还明确了一条重要的故障路径:如果某个指标无法计算期望副本数,而其他可用指标建议缩容,HPA 会跳过缩容;有效的扩容建议仍可继续执行。
示例显式设置了 behavior。如果省略 scaleDown.stabilizationWindowSeconds,文档所述默认值是 300 秒;扩容的默认稳定窗口为 0。请固定集群版本并核对控制器设置,因为运维人员可以修改集群级行为。
只有真正就绪的副本才计入容量
进程已经启动,不等于它已能安全承接生产流量。就绪条件应覆盖实际服务所需状态:配置已加载、监听器已启动、必要的本地状态已初始化,并且关键依赖符合既定故障策略。
Kubernetes HPA 会保守处理缺失指标和尚未就绪的 Pod,但这不能替代正确的就绪探针。需要分别测量镜像拉取、调度、配置传播、密钥加载和预热时间,再据此设置最低副本数与容量余量,覆盖整个等待周期。
避免让探针陷入循环依赖:如果某个可选依赖失效时系统本就计划降级服务,就绪规则不应强制要求该依赖健康。探针必须与真实可用性契约一致。
缩容时避免丢失有效工作
缩容发生时,流量往往仍在继续。Kubernetes 的 Pod 终止流程会把终止中的端点标记为不可用于常规流量,并在配置的宽限期内向进程发送停止信号。应用仍需获得足够时间,停止接收新工作并完成或转移适合排空的连接。
对网关工作负载,应执行以下步骤:
- 将缩容稳定窗口设得长于正常指标抖动周期;
- 通过就绪状态和端点状态停止向该 Pod 分配新流量;
- 按协议策略排空 HTTP keep-alive、流和升级连接;
- 根据实测排空时间设置
terminationGracePeriodSeconds; - 验证宽限期到期、进程被强制终止时的行为。
PodDisruptionBudget 会限制符合条件、通过驱逐机制发起的自愿中断。它不能替代 HPA 最低副本数、滚动发布的 surge/unavailable 设置、拓扑分布或连接排空测试。
在弹性扩容前设置准入控制
自动扩缩容是延迟反馈。突发流量可能在下一次指标采样、副本计算、调度和就绪转换前就已到达。应使用有边界的请求速率、并发量、请求体大小、超时和队列策略,在这一时间窗口内保护现有热容量及其依赖。
扩容还必须服从外部限制:
- 节点与 IP 地址容量;
- 负载均衡器目标注册;
- 控制面与配置传播;
- 证书和机密信息分发;
- 上游连接池和数据库限制;
- 第三方配额和成本上限。
验证清单
- 容量测试是否匹配生产协议、插件链、负载和上游延迟?
- 在 CPU 利用率驱动 HPA 前,是否已设置 CPU 请求值?
- 能否从源查询、指标 API 一直追踪到 HPA 状态中的自定义指标?
- 指标缺失时是否会按预期阻止不安全缩容?
- 在新副本就绪前,热容量能否承受突发流量?
- 下游饱和时,扩容是否会停止或转为削峰?
- 终止中的 Pod 是否停止接收新流量,并获得足够排空时间?
- 长连接、重试和强制终止是否符合设计?
- 节点维护期间,最低副本数、拓扑和中断设置是否经过测试?
- 运维人员能否还原每次扩缩容由哪个指标和策略触发?
常见问题
CPU 是否足以作为 API 网关 HPA 指标?
对于稳定且计算密集的工作负载,有时足够。当连接数、请求成本、排队或下游容量与 CPU 不再同步时,应增加能够反映最先出现的实际饱和点的指标。
是否应该让延迟直接触发扩容?
只有在区分网关饱和与上游延迟之后才这样做。否则,自动扩缩容器可能会给已经故障的依赖增加更多网关压力。
API 网关能否缩容到零?
对于面向互联网的同步网关,这通常不合适,因为第一个请求需要先有监听器才能触发有效处理。除非另一个入口能够安全排队或重定向流量,而且平台明确支持所选的缩零路径,否则应保留经过测试的热容量。
后续步骤
将弹性扩展与并发预算和负载削减、安全的超时与重试策略,以及基于证据的网关优化结合起来。
