2. HPA 核心组件解析:Metrics Server、Custom Metrics API、External Metrics API 的作用与配置

HPA(Horizontal Pod Autoscaler)的弹性伸缩决策依赖于可靠的指标数据源。Kubernetes 生态中,Metrics Server、Custom Metrics API 和 External Metrics API 构成了 HPA 的三大核心数据支柱。理解它们的作用域、数据流和配置方式,是进行精准调优的前提。

2.1 三大指标体系与数据流架构

HPA 通过标准的 metrics.k8s.io、custom.metrics.k8s.io 和 external.metrics.k8s.io API 组获取指标。下图展示了 HPA 控制器如何从不同数据源拉取指标并驱动扩缩容决策。

HPA 三大指标数据源架构图 HPA 三大指标数据源架构 HPA 控制器 metrics.k8s.io custom.metrics.k8s.io external.metrics.k8s.io Metrics Server CPU / 内存 / 网络 Custom Metrics API 应用自定义指标 External Metrics API 外部系统指标 Kubelet / cAdvisor 节点 & Pod 资源 Prometheus Adapter 应用业务指标 云服务 / 外部系统 队列、DB、网关 说明: • Metrics Server 默认安装,提供基础资源指标,延迟低但指标类型有限。 • Custom Metrics API 需要适配器(如 Prometheus Adapter)将应用指标注册到 API Server。 • External Metrics API 用于拉取集群外指标(如云服务队列长度),同样需要适配器实现。

2.2 Metrics Server:基础资源指标的基石

Metrics Server 是 Kubernetes 集群中默认的资源指标聚合器。它从每个节点上的 Kubelet(通过 cAdvisor)收集 CPU 和内存使用数据,并通过 metrics.k8s.io API 对外暴露。

2.2.1 核心作用

  • 轻量级采集:仅采集 CPU 和内存的实时使用量,不存储历史数据。
  • 标准 API 接口:提供 /apis/metrics.k8s.io/v1beta1 端点,供 HPA 和 kubectl top 命令使用。
  • 自动发现:自动发现集群中所有节点和 Pod,无需手动配置指标白名单。

2.2.2 安装与验证

Metrics Server 通常通过 YAML 清单或 Helm Chart 安装。以下为典型安装命令:

# 使用官方 YAML 安装(适用于大多数集群)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 验证安装状态
kubectl get deployment metrics-server -n kube-system

# 测试指标采集是否正常
kubectl top nodes
kubectl top pods --all-namespaces
调优要点: Metrics Server 默认每 15 秒采集一次数据。对于需要更灵敏响应的场景,可通过 --metric-resolution 参数调整采集间隔(例如 --metric-resolution=10s),但需注意增加 Kubelet 负载。

2.3 Custom Metrics API:应用级自定义指标

当基础资源指标无法准确反映应用负载时(例如基于 QPS、请求延迟、队列深度),就需要 Custom Metrics API。它允许将任意应用指标注册到 Kubernetes API Server,使 HPA 能够基于这些指标进行伸缩。

2.3.1 工作原理

Custom Metrics API 本身是一个 API 扩展,需要后端适配器(Adapter)来实现。最常用的适配器是 Prometheus Adapter,它从 Prometheus 中查询指标,并将其转换为 custom.metrics.k8s.io 格式。

2.3.2 配置示例:Prometheus Adapter

以下是一个 Prometheus Adapter 的配置片段,将名为 http_requests_per_second 的 Prometheus 指标暴露为 Custom Metric:

# adapter-config.yaml
rules:
  - seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
    resources:
      overrides:
        namespace: {resource: "namespace"}
        pod: {resource: "pod"}
    name:
      matches: "^(.*)_total"
      as: "${1}_per_second"
    metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'

部署适配器后,HPA 可以引用该指标:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: webapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: webapp
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: 100
常见陷阱: Custom Metrics API 的指标延迟通常比 Metrics Server 高(可能达到 30-60 秒)。在配置 HPA 的 --horizontal-pod-autoscaler-sync-period 时,建议设置为指标延迟的 2-3 倍,避免因数据抖动导致频繁扩缩容。

2.4 External Metrics API:跨集群与外部指标

External Metrics API 用于获取集群外部的指标数据,例如云服务商的队列长度(AWS SQS、Azure Service Bus)、数据库连接数、外部网关的请求量等。它同样需要适配器实现,但指标不绑定到特定的 Kubernetes 对象(如 Pod 或 Namespace)。

2.4.1 典型使用场景

场景 外部指标示例 适配器方案
消息队列驱动伸缩 AWS SQS ApproximateNumberOfMessagesVisible AWS CloudWatch Adapter / KEDA
数据库连接池监控 Redis 活跃连接数、MySQL 线程数 Prometheus + 外部 Exporter
CDN / 网关流量 CloudFront 请求速率、API Gateway 延迟 自定义 Adapter 或 KEDA Scaler

2.4.2 配置示例:基于 AWS SQS 队列长度

使用 KEDA(Kubernetes Event-driven Autoscaling)作为 External Metrics 适配器,可以轻松实现基于 SQS 队列长度的 HPA:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: sqs-consumer-scaledobject
spec:
  scaleTargetRef:
    name: sqs-consumer
  triggers:
  - type: aws-sqs-queue
    metadata:
      queueURL: https://sqs.us-east-1.amazonaws.com/123456789012/my-queue
      queueLength: "5"          # 目标队列长度
      awsRegion: "us-east-1"
      identityOwner: "operator"

KEDA 会自动在集群中创建对应的 External Metric,HPA 可以直接引用:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: sqs-consumer-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: sqs-consumer
  minReplicas: 1
  maxReplicas: 20
  metrics:
  - type: External
    external:
      metric:
        name: keda-metrics-aws-sqs-queue-...  # KEDA 自动生成的指标名
      target:
        type: AverageValue
        averageValue: 5

2.5 三大指标 API 对比总结

特性 Metrics Server Custom Metrics API External Metrics API
API 组 metrics.k8s.io custom.metrics.k8s.io external.metrics.k8s.io
指标范围 CPU、内存(节点/Pod) 应用自定义指标(Pod/Namespace 级别) 集群外部指标(全局)
数据源 Kubelet / cAdvisor Prometheus、Datadog、自定义 Exporter 云服务 API、消息队列、数据库
安装复杂度 低(官方 YAML 一键部署) 中(需部署 Adapter 并配置规则) 中-高(需适配器或 KEDA)
指标延迟 10-20 秒 30-60 秒(取决于 Prometheus 采集间隔) 30-120 秒(取决于外部系统响应)
典型用途 基础资源弹性 业务负载弹性(QPS、延迟) 事件驱动弹性(队列、外部流量)

2.6 配置检查清单

生产环境配置建议:
  • Metrics Server:确保资源请求和限制合理(推荐 50m CPU / 100Mi 内存),开启 --kubelet-use-node-status-port 以兼容新版 Kubelet。
  • Custom Metrics Adapter:为 Prometheus Adapter 配置缓存时间(--cache-ttl),避免频繁查询 Prometheus 导致性能瓶颈。
  • External Metrics Adapter:使用 KEDA 时,注意设置 pollingInterval(默认 30 秒)和 cooldownPeriod(默认 300 秒),防止外部指标抖动引发无效伸缩。
  • 安全加固:所有 Adapter 应通过 RBAC 限制对 API Server 的访问,仅暴露必要的指标。