4. HPA 核心机制:Metrics Server vs Prometheus Adapter、自定义指标与外部指标
Horizontal Pod Autoscaler(HPA)是 Kubernetes 控制面弹性伸缩的核心组件。理解 HPA 的指标来源与适配器机制,是排查弹性伸缩故障的前提。本章深入剖析 Metrics Server 与 Prometheus Adapter 的架构差异、自定义指标与外部指标的数据流,以及常见故障模式。
4.1 指标来源架构对比
Kubernetes 原生 HPA 支持三类指标来源,分别对应不同的数据采集与暴露路径:
| 指标类型 | 数据源 | API 端点 | 典型用途 |
|---|---|---|---|
| Resource Metrics | Metrics Server(kubelet/cAdvisor) | metrics.k8s.io |
CPU / 内存利用率 |
| Custom Metrics | Prometheus Adapter / 自定义 API | custom.metrics.k8s.io |
Pod 级别业务指标(QPS、请求延迟) |
| External Metrics | Prometheus Adapter / 云厂商 API | external.metrics.k8s.io |
集群外部指标(队列长度、数据库连接数) |
故障排查要点: 当 HPA 无法获取指标时,首先检查对应 API 服务是否注册到 API Server 的聚合层。使用
kubectl get apiservice 确认 v1beta1.metrics.k8s.io、v1beta1.custom.metrics.k8s.io、v1beta1.external.metrics.k8s.io 的状态是否为 True。
4.2 Metrics Server 与 Prometheus Adapter 核心差异
两者虽然都提供指标给 HPA,但在架构定位、数据精度、扩展性方面存在本质区别:
| 维度 | Metrics Server | Prometheus Adapter |
|---|---|---|
| 数据来源 | kubelet Summary API(内存中实时聚合) | Prometheus 时序数据库(历史 + 实时) |
| 指标范围 | 仅 CPU / 内存 / 网络 / 磁盘(资源类) | 任意 Prometheus 采集的指标(业务 + 资源) |
| 数据精度 | 实时快照,无历史聚合 | 支持 rate/avg/p95 等聚合函数 |
| 扩展性 | 单副本,集群内轻量部署 | 支持多副本、自定义查询、指标重命名 |
| 故障影响面 | 仅影响 Resource HPA | 影响所有 Custom/External HPA |
常见故障: Metrics Server 因 kubelet 证书轮换或节点压力导致采集超时,HPA 会回退到
Unknown 状态并停止伸缩。Prometheus Adapter 则常因 PromQL 查询超时(默认 30s)或指标标签不匹配导致返回空列表。
4.3 自定义指标数据流与故障点
自定义指标从 Prometheus 采集到 HPA 决策的完整路径包含 5 个关键节点:
4.4 外部指标的特殊性
外部指标(External Metrics)与自定义指标的关键区别在于:外部指标不绑定到任何 Kubernetes 对象(Pod/Namespace),而是直接引用集群外部的数据源。典型场景包括:
- 消息队列长度:Kafka 消费者滞后、RabbitMQ 队列深度
- 数据库连接池:MySQL 活跃连接数、Redis 内存使用率
- 云服务指标:AWS SQS 消息数、GCP Pub/Sub 订阅积压
配置示例: 外部指标在 HPA 中通过
type: External 声明,metric.selector.matchLabels 用于过滤 Adapter 返回的指标。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: consumer-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: consumer
minReplicas: 2
maxReplicas: 10
metrics:
- type: External
external:
metric:
name: kafka_consumer_lag
selector:
matchLabels:
topic: "orders"
group: "payment-group"
target:
type: AverageValue
averageValue: "100"
4.5 指标适配器配置对比
Prometheus Adapter 通过 configmap 定义指标发现规则。以下对比两种常见配置模式:
| 配置模式 | 适用场景 | 示例规则 | 故障排查方向 |
|---|---|---|---|
| pods | Pod 级别指标(QPS、延迟) | pods: { metric: 'http_requests', matches: 'pod' } |
检查 Pod 标签是否与 Prometheus 标签匹配 |
| object | 单个对象指标(Ingress 流量) | object: { metric: 'nginx_connections', describedObject: 'Ingress' } |
确认对象名称与 Prometheus label 一致 |
| external | 集群外部指标(队列、DB) | external: { metric: 'kafka_lag', labelSelector: 'topic' } |
验证 Adapter 能否直接访问外部数据源 |
4.6 故障排查清单
当 HPA 无法基于自定义/外部指标伸缩时,按以下顺序排查:
- 验证 API 可用性:
kubectl get apiservice | grep metrics确认状态为 True - 测试 Adapter 响应:
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1返回非空列表 - 检查 PromQL 查询:在 Prometheus UI 中手动执行 Adapter 配置的查询语句
- 确认指标标签:HPA 的
matchLabels必须与 Prometheus 指标标签完全一致 - 查看 Adapter 日志:
kubectl logs -n monitoring prometheus-adapter-xxx搜索 error/warn - 验证 HPA 事件:
kubectl describe hpa <name>查看 Conditions 和 Events
关键故障模式: 当 Prometheus Adapter 返回的指标值类型为
int64 而 HPA 期望 float64 时,HPA 会忽略该指标并记录 FailedGetResourceMetric 事件。此时需要在 Adapter 配置中显式指定 type: AverageValue 或使用 value: 100m 格式。