Kubernetes 指标原生直方图支持

特性状态: Kubernetes v1.36 [alpha](默认禁用)

Kubernetes 组件可以以 Prometheus 原生直方图格式暴露直方图指标, 以及经典直方图格式。 原生直方图使用指数桶边界而不是固定边界,从而显著提高存储效率、改善查询性能,并更精细地了解分布情况。

准备工作

要使用原生直方图,你需要:

  • Kubernetes v1.36 或更高版本,并启用 NativeHistograms 特性门控
  • Prometheus 2.40 或更高版本来抓取和存储原生直方图。 推荐使用 Prometheus 3.0+ 进行 per-job 配置。

什么是原生直方图?

经典 Prometheus 直方图使用固定桶边界(例如, [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10] 秒)。 每个桶创建一个单独的时间序列(_bucket_count_sum),这可能导致:

  • 高存储成本:因为每个直方图生成许多时间序列。
  • 精度问题:因为宽桶范围内的数据点无法区分。 例如,完成时间为 1µs 和 4ms 的请求都落入同一个 le="0.005" 桶中。

原生直方图 通过使用自动适应数据分布的指数桶边界来解决这些限制。好处包括:

  • 每个直方图指标的时间序列数量减少约 10 倍,显著降低 Prometheus 存储成本并提高查询性能。
  • 更细粒度的分辨率,用于检测性能回归和设置精确的 SLO 阈值。

工作原理

NativeHistograms 特性门控启用时,Kubernetes 组件同时以经典格式和原生格式(双暴露)暴露直方图指标。 返回的格式取决于 HTTP 请求中的 Accept 头 (Prometheus 内容协商)。 Prometheus 根据你的抓取配置自动设置此头; 只有在直接查询 /metrics 端点时才需要关注它。

  • 文本格式(Accept: text/plain,OpenMetrics 1.0):仅返回经典直方图桶。 向后兼容所有现有工具。

    # Classic histogram buckets (always present)
    apiserver_request_duration_seconds_bucket{le="0.005"} 1000
    apiserver_request_duration_seconds_bucket{le="0.01"} 2000
    ...
    apiserver_request_duration_seconds_bucket{le="+Inf"} 10000
    apiserver_request_duration_seconds_count 10000
    apiserver_request_duration_seconds_sum 450.5
    
  • Protobuf 格式(Accept: application/vnd.google.protobuf):包含经典桶和原生直方图数据。 当在相应抓取作业的 Prometheus 抓取配置中设置 scrape_native_histograms: true 时,Prometheus 自动请求此格式。

这种双暴露策略确保:

  • 现有仪表板和告警继续正常工作,无需更改。
  • 用户可以按自己的节奏将查询迁移到原生直方图。
  • Prometheus 存储所配置接收的格式。

启用原生直方图

启用原生直方图是一个两步过程:在 Kubernetes 组件上启用特性门控, 并配置 Prometheus 抓取原生直方图。

步骤 1:启用 Kubernetes 特性门控

在你想要暴露原生直方图的 Kubernetes 组件上启用 NativeHistograms 特性门控:

--feature-gates=NativeHistograms=true

此特性门控适用于以下组件:

  • kube-apiserver
  • kube-controller-manager
  • kube-scheduler
  • kubelet
  • kube-proxy

每个组件的指标是独立的;你可以按组件启用或禁用特性门控。

步骤 2:配置 Prometheus

Prometheus 配置取决于你的 Prometheus 版本。

Prometheus 版本 原生直方图支持 配置 备注
< 2.40 不适用 仅经典直方图。启用 Kubernetes 特性门控无效。
2.40 – 2.x 实验性 --enable-feature=native-histograms(全局) 全有或全无;无 per-job 控制。
3.0 – 3.7 稳定 Per-job scrape_native_histogramsalways_scrape_classic_histograms 推荐使用 per-job 配置。全局标志仍然支持。
3.8 稳定 Per-job 配置(细粒度控制必需) 全局标志仅更改所有作业的默认值。
3.9+ 稳定 仅 Per-job scrape_native_histograms 全局标志已移除。必须使用 per-job 配置。

对于 Prometheus 3.x,使用 per-job 配置进行细粒度控制:

scrape_configs:
  - job_name: 'kubernetes-apiservers'
    scrape_native_histograms: true            # 摄入原生直方图
    always_scrape_classic_histograms: true     # 迁移期间保留经典格式

在迁移期间将两个选项都设置为 true。 这允许你摄入原生直方图,同时为现有仪表板保留经典直方图。

说明:

原生直方图需要 Protobuf 暴露格式。 这由 Prometheus 自动处理。但是,如果你自定义了 scrape_protocols, 请确保 PrometheusProto 包含在列表中。

迁移仪表板和告警

注意:

如果 Prometheus 配置了 scrape_native_histograms: truealways_scrape_classic_histograms: false(默认值),Prometheus 仅摄入原生直方图。 使用经典直方图查询的现有仪表板(例如 histogram_quantile(..._bucket...))将不显示数据。 在迁移期间始终将 always_scrape_classic_histograms: true 设置为 true。

从经典直方图查询迁移到原生直方图查询时,请遵循此工作流程:

  1. 启用两种格式:在你的 Prometheus 抓取配置中设置 scrape_native_histograms: truealways_scrape_classic_histograms: true
  1. 迁移查询:将仪表板查询和告警表达式从经典直方图函数更新为原生直方图等效函数。

    经典查询:

    histogram_quantile(0.99, rate(apiserver_request_duration_seconds_bucket[5m]))
    

    原生直方图查询:

    histogram_quantile(0.99, rate(apiserver_request_duration_seconds[5m]))
    
  1. 在预发布环境中验证:在推送到生产环境之前,使用原生直方图查询测试所有仪表板和告警。
  1. 禁用经典抓取:迁移完成并验证后,设置 always_scrape_classic_histograms: false 以减少存储开销。

禁用原生直方图

你可以随时使用以下两种方法之一禁用原生直方图:

  • Prometheus 端(最快,无需重启 Kubernetes;仅限 Prometheus 3.x): 按抓取作业设置 scrape_native_histograms: false。 Prometheus 在下一个抓取间隔恢复抓取经典格式。
  • Kubernetes 特性门控:使用 --feature-gates=NativeHistograms=false 重启组件。 重启后仅暴露经典直方图格式。

当原生直方图被禁用时,指标端点仅恢复为经典直方图格式。 Prometheus 中的历史原生直方图数据仍然可查询。

故障排除

  • 启用原生直方图后仪表板不显示数据 : 当 Prometheus 配置了 scrape_native_histograms: truealways_scrape_classic_histograms: false(默认值),且你的仪表板仍使用经典直方图查询 (例如 histogram_quantile(..._bucket...))时,会发生这种情况。

    修复:在迁移仪表板时设置 always_scrape_classic_histograms: true 以恢复经典格式摄入。

  • 启用原生直方图后内存使用量增加 : 原生直方图桶存储的内存小幅增加是预期的,每个直方图最多有 160 个桶的限制。 监视 process_resident_memory_bytes 以发现意外增加。

    修复:如果内存压力严重,在 Prometheus 中禁用原生直方图摄入 (scrape_native_histograms: false)或禁用 Kubernetes 特性门控。

  • Prometheus 日志中出现未知指标格式错误 : 你的 Prometheus 版本太旧,无法理解原生直方图。

    修复:将 Prometheus 升级到 2.40+ 或在 Kubernetes 中禁用原生直方图。

  • 不确定原生直方图是否正在被暴露 : 通过在 Prometheus 中查询 kubernetes_feature_enabled{name="NativeHistograms"} 来检查特性门控状态。值为 1 表示该特性已启用。 你还可以使用 protobuf 格式直接查询指标端点:

    curl -H "Accept: application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited" \
      https://<component-address>/metrics
    

    响应应包含直方图指标的原生地直方图编码。

参考


最后修改 April 24, 2026 at 5:06 PM PST: [zh-cn]Add native-histograms (3de665e970)