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 个关键节点:

自定义指标 HPA 数据流与故障点 ① Prometheus 采集 ② Adapter 查询 ③ API 聚合 ④ HPA 控制器 ⑤ 副本调整 常见故障点 ① Prometheus 采集:指标缺失、标签不一致、采集间隔 > HPA 同步周期(15s) ② Adapter 查询:PromQL 语法错误、查询超时、series 为空 ③ API 聚合:APIService 未注册、证书不匹配、Adapter 崩溃 ④ HPA 控制器:指标值类型错误(int vs float)、目标值配置错误 ⑤ 副本调整:资源配额不足、PDB 阻止、控制器循环冲突

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 无法基于自定义/外部指标伸缩时,按以下顺序排查:

  1. 验证 API 可用性:kubectl get apiservice | grep metrics 确认状态为 True
  2. 测试 Adapter 响应:kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 返回非空列表
  3. 检查 PromQL 查询:在 Prometheus UI 中手动执行 Adapter 配置的查询语句
  4. 确认指标标签:HPA 的 matchLabels 必须与 Prometheus 指标标签完全一致
  5. 查看 Adapter 日志:kubectl logs -n monitoring prometheus-adapter-xxx 搜索 error/warn
  6. 验证 HPA 事件:kubectl describe hpa <name> 查看 Conditions 和 Events
关键故障模式: 当 Prometheus Adapter 返回的指标值类型为 int64 而 HPA 期望 float64 时,HPA 会忽略该指标并记录 FailedGetResourceMetric 事件。此时需要在 Adapter 配置中显式指定 type: AverageValue 或使用 value: 100m 格式。