GKE 正在把 Prometheus 指标接入 HPA 的链路变短:通过扩展 AutoscalingMetric,集群可以直接查询 Cloud Monitoring 中由 Google Managed Service for Prometheus 管理的指标,再把结果交给 Horizontal Pod Autoscaler。平台团队不再需要单独部署、升级和监控 Prometheus Adapter 或 Stackdriver Custom Metrics Adapter。
这项能力目前处于预览阶段,但它已经覆盖了几个常见场景:按照 Pub/Sub 积压消息数扩缩 worker、按照 QPS 扩缩推理服务,以及用时间窗口、速率或直方图分位数表达更贴近业务目标的扩缩容信号。
少一层 Adapter,少一组故障点
传统的外部指标链路通常是:
HPA -> Kubernetes Metrics API -> Adapter Pod -> Monitoring/Prometheus
Adapter 虽然解决了指标格式转换问题,却也进入了关键扩缩容回路。团队必须处理它的安装、配置、补丁、容量、可用性和 IAM 权限;一旦 Adapter 不可用,即使业务指标仍在正常上报,HPA 也可能拿不到数据。
GKE 内置方案把配置收敛到两个 Kubernetes 对象:
AutoscalingMetric保存 PromQL 查询,并声明结果是全局指标还是逐 Pod 指标。- 标准
HorizontalPodAutoscaler通过约定的指标名称引用查询结果。
指标名称格式如下:
autoscaling.gke.io|<autoscaling-metric-name>|<metric-name>
相关控制器运行在 GKE 控制平面。只有 PromQL 指标被实际请求时,系统才会在用户节点上部署所需组件;没有配置 Prometheus 指标时,对应控制器会关闭,以减少闲置资源开销。
需要区分两个时间尺度:GKE 早先的 Pod 自定义指标通路可将读取延迟压缩到约 5 秒,而这里介绍的 Prometheus 后端会按约 15 秒的周期轮询。它适合秒级到分钟级的容量调节,但不应被当作毫秒级流量保护机制。突发保护仍应依赖队列缓冲、限流、过载保护或预留容量。
可复制示例:根据 Pub/Sub 积压扩缩 worker
下面假设三个条件已经满足:
- 集群已启用相应的 GKE 预览能力;
- Pub/Sub 指标已经进入同一项目的 Cloud Monitoring;
- 名为
worker-deployment的 Deployment 已经存在。
将 my-subscription 改成实际订阅 ID,然后保存为 pubsub-hpa.yaml:
apiVersion: autoscaling.gke.io/v1beta1
kind: AutoscalingMetric
metadata:
name: gmp-metric
spec:
metrics:
- promql:
name: pubsub-queue-depth
query: |
{
"pubsub.googleapis.com/subscription/num_undelivered_messages",
subscription_id="my-subscription"
}
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: worker-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: worker-deployment
minReplicas: 1
maxReplicas: 10
metrics:
- type: External
external:
metric:
name: autoscaling.gke.io|gmp-metric|pubsub-queue-depth
target:
type: AverageValue
averageValue: "100"
应用并检查资源:
kubectl apply -f pubsub-hpa.yaml
kubectl get autoscalingmetric gmp-metric -o yaml
kubectl get hpa worker-hpa -w
这里的目标是让每个副本平均承担约 100 条未确认消息。例如,查询返回 700,而当前每个副本的目标是 100,HPA 会倾向于把副本数调整到约 7 个,但最终结果仍会受到 maxReplicas、HPA 容忍区间、稳定窗口以及指标可用性的影响。
上线前应主动制造一批测试消息,并同时观察 HPA、Deployment 和队列深度:
kubectl describe hpa worker-hpa
kubectl get deployment worker-deployment
kubectl get pods -w
如果 HPA 显示指标未知,不要立刻调大副本上限。先检查 AutoscalingMetric 状态、PromQL 是否返回单个数值、订阅标签是否正确,以及指标是否确实存在于当前项目。
用 PromQL 把时间窗口纳入扩缩容决策
瞬时指标容易抖动。PromQL 的价值不只是“能读取 Prometheus”,而是能在交给 HPA 前完成速率、滑动平均和分位数计算。
例如,下面的资源按 Pod 计算最近五分钟的平均内存工作集:
apiVersion: autoscaling.gke.io/v1beta1
kind: AutoscalingMetric
metadata:
name: per-pod-stored-metric
spec:
metrics:
- promql:
name: container-memory-metric
query: |
sum by ("pod") (
avg_over_time({"container_memory_working_set_bytes"}[5m])
)
type: Pods
这里有两个关键约束:
- 查询结果必须保留 Pod 名称标签,否则系统无法把数值关联到各个 Pod。
type: Pods表示返回的是逐 Pod 序列,不是队列深度那样的全局聚合值。
类似地,可以用 rate() 计算请求速率,或通过直方图查询得到 P95 延迟。不过,延迟指标作为扩缩容信号时要格外谨慎:延迟上涨可能来自下游数据库、第三方 API 或锁竞争,盲目增加 Pod 反而可能加重下游压力。更稳妥的做法通常是把 QPS、队列深度或并发量作为主要信号,把延迟用于告警和扩缩容上限保护。
安全、成本与 scale-to-zero 边界
同一项目内,Kubernetes Default Node Service Agent 默认具备读取 Cloud Monitoring 和 Google Managed Service for Prometheus 的权限,因此通常不需要为 Adapter 再创建服务账号、密钥或 Workload Identity 映射。这降低了配置复杂度,但不等于可以忽略权限审计;跨项目读取、受限环境和自定义组织策略仍需单独验证。
新链路还可以配合 HPA 的 scale-to-zero 能力处理空闲 worker。队列为空时把副本降到零很有吸引力,但从零恢复存在冷启动问题。对于有严格响应时间要求的任务,需要评估镜像拉取、节点容量、应用启动和依赖连接所花费的时间,并考虑使用 CapacityBuffers API 预留恢复容量。
上线前检查清单
在生产环境采用时,建议逐项确认:
- PromQL 查询在正常、空闲和异常流量下都返回预期结果。
- 全局指标和逐 Pod 指标分别使用了正确的类型与标签。
minReplicas、maxReplicas和单 Pod 目标值经过压测,而不是凭经验填写。- 指标中断时有告警,并明确 HPA 无法读取指标时的运行预期。
- 扩容速度能覆盖业务增长速度,缩容策略不会导致频繁抖动。
- 下游系统能够承受扩容后增加的并发。
- 预览功能的兼容性和变更风险符合生产环境要求。
GKE 原生 PromQL 支持最大的变化,并不是多了一种查询语法,而是把外部 Adapter 从关键路径中移除。对于已经使用 Cloud Monitoring 和托管 Prometheus 的团队,这能明显缩短部署清单并减少维护面;对于自建 Prometheus、跨项目指标或高度定制化链路,则应在功能进入正式可用阶段、相关后端获得支持后再评估迁移。