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 以抓取原生直方图。

第一步:启用 Kubernetes 特性门控

在希望公开原生直方图的 Kubernetes 组件上启用 NativeHistograms 特性门控

--feature-gates=NativeHistograms=true

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

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

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

第二步:配置 Prometheus

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

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

对于 Prometheus 3.x,请使用按作业配置以获得细粒度控制

scrape_configs:
  - job_name: 'kubernetes-apiservers'
    scrape_native_histograms: true            # Ingest native histograms
    always_scrape_classic_histograms: true     # Keep classic format during migration

在迁移期间将这两个选项均设置为 true。这允许你在摄取原生直方图的同时,为现有的仪表板保留传统直方图。

说明

原生直方图需要 Protobuf 导出格式。Prometheus 默认会自动处理此项。但是,如果你自定义了 scrape_protocols,请确保列表中包含了 PrometheusProto

迁移仪表板和告警

注意

如果 Prometheus 配置了 scrape_native_histograms: truealways_scrape_classic_histograms: false(默认值),Prometheus 将仅摄取原生直方图。使用传统直方图查询(例如 histogram_quantile(..._bucket...))的现有仪表板将显示无数据。在迁移期间,请务必设置 always_scrape_classic_histograms: true

从传统直方图查询迁移到原生直方图查询时,请遵循以下工作流程

  1. 同时启用两种格式:在你的 Prometheus 抓取配置中设置 scrape_native_histograms: truealways_scrape_classic_histograms: true

  2. 迁移查询:将仪表板查询和告警表达式从传统直方图函数更新为原生直方图等效函数。

    传统查询

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

    原生直方图查询

    histogram_quantile(0.99, rate(apiserver_request_duration_seconds[5m]))
    
  3. 在预生产环境验证:在推送到生产环境之前,使用原生直方图查询测试所有仪表板和告警。

  4. 禁用传统抓取:一旦迁移完成并经过验证,设置 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
    

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

参考资料


上次修改时间:2026 年 2 月 26 日 下午 12:28 PST:关于原生直方图的文档更新 (b648379c62)