插桩
1 - Kubernetes 组件 SLI 指标
Kubernetes v1.32 [stable](默认启用)默认情况下,Kubernetes 1.36 会为每个 Kubernetes 组件的二进制文件发布服务等级指标(SLI)。
此指标端点被暴露在每个组件提供 HTTPS 服务的端口上,路径为 /metrics/slis。
从 v1.27 版本开始,对每个 Kubernetes 组件而言,
ComponentSLIs 特性门控都是默认启用的。
SLI 指标
启用 SLI 指标时,每个 Kubernetes 组件暴露两个指标,按照健康检查添加标签:
- 计量值(表示健康检查的当前状态)
- 计数值(记录观察到的每个健康检查状态的累计次数)
你可以使用此指标信息计算每个组件的可用性统计信息。例如,API 服务器检查 etcd 的健康。 你可以计算并报告 etcd 的可用或不可用情况,具体由其客户端(即 API 服务器)进行报告。
Prometheus 计量表数据看起来类似于:
# HELP kubernetes_healthcheck [ALPHA] This metric records the result of a single healthcheck.
# TYPE kubernetes_healthcheck gauge
kubernetes_healthcheck{name="autoregister-completion",type="healthz"} 1
kubernetes_healthcheck{name="autoregister-completion",type="readyz"} 1
kubernetes_healthcheck{name="etcd",type="healthz"} 1
kubernetes_healthcheck{name="etcd",type="readyz"} 1
kubernetes_healthcheck{name="etcd-readiness",type="readyz"} 1
kubernetes_healthcheck{name="informer-sync",type="readyz"} 1
kubernetes_healthcheck{name="log",type="healthz"} 1
kubernetes_healthcheck{name="log",type="readyz"} 1
kubernetes_healthcheck{name="ping",type="healthz"} 1
kubernetes_healthcheck{name="ping",type="readyz"} 1
而计数器数据看起来类似于:
# HELP kubernetes_healthchecks_total [ALPHA] This metric records the results of all healthcheck.
# TYPE kubernetes_healthchecks_total counter
kubernetes_healthchecks_total{name="autoregister-completion",status="error",type="readyz"} 1
kubernetes_healthchecks_total{name="autoregister-completion",status="success",type="healthz"} 15
kubernetes_healthchecks_total{name="autoregister-completion",status="success",type="readyz"} 14
kubernetes_healthchecks_total{name="etcd",status="success",type="healthz"} 15
kubernetes_healthchecks_total{name="etcd",status="success",type="readyz"} 15
kubernetes_healthchecks_total{name="etcd-readiness",status="success",type="readyz"} 15
kubernetes_healthchecks_total{name="informer-sync",status="error",type="readyz"} 1
kubernetes_healthchecks_total{name="informer-sync",status="success",type="readyz"} 14
kubernetes_healthchecks_total{name="log",status="success",type="healthz"} 15
kubernetes_healthchecks_total{name="log",status="success",type="readyz"} 15
kubernetes_healthchecks_total{name="ping",status="success",type="healthz"} 15
kubernetes_healthchecks_total{name="ping",status="success",type="readyz"} 15
使用此类数据
组件 SLI 指标端点旨在以高频率被抓取。
高频率抓取意味着你最终会获得更细粒度的计量信号,然后可以将其用于计算 SLO。
/metrics/slis 端点为各个 Kubernetes 组件提供了计算可用性 SLO 所需的原始数据。
2 - CRI Pod 和容器指标
Kubernetes v1.23 [alpha]
kubelet 通过
cAdvisor 收集 Pod 和容器指标。作为一个 Alpha 特性,
Kubernetes 允许你通过容器运行时接口(CRI)
配置收集 Pod 和容器指标。要使用基于 CRI 的收集机制,你必须启用 PodAndContainerStatsFromCRI
特性门控
并使用兼容的 CRI 实现(containerd >= 1.6.0, CRI-O >= 1.23.0)。
CRI Pod 和容器指标
当启用 PodAndContainerStatsFromCRI 时,kubelet 轮询底层容器运行时以获取
Pod 和容器统计信息,而不是直接使用 cAdvisor 检查主机系统。同直接使用 cAdvisor
收集信息相比,依靠容器运行时获取这些信息的好处包括:
- 潜在的性能改善,如果容器运行时在正常操作中已经收集了这些信息。 在这种情况下,这些数据可以被重用,而不是由 kubelet 再次进行聚合。
- 这种做法进一步解耦了 kubelet 和容器运行时。 对于使用 kubelet 来在主机上运行进程的容器运行时,其行为可用 cAdvisor 观测; 对于其他运行时(例如,使用虚拟化的容器运行时)而言, 这种做法提供了允许收集容器运行时指标的可能性。
3 - 节点指标数据
kubelet 在节点、卷、Pod 和容器级别收集统计信息, 并在 Summary API 中输出这些信息。
你可以通过 Kubernetes API 服务器将代理的请求发送到 stats Summary API。
下面是一个名为 minikube 的节点的 Summary API 请求示例:
kubectl get --raw "/api/v1/nodes/minikube/proxy/stats/summary"
下面是使用 curl 所执行的相同 API 调用:
# 你需要先运行 "kubectl proxy"
# 更改 8080 为 "kubectl proxy" 指派的端口
curl http://localhost:8080/api/v1/nodes/minikube/proxy/stats/summary
说明:
从 metrics-server 0.6.x 开始,metrics-server 查询 /metrics/resource
kubelet 端点,不查询 /stats/summary。
概要指标 API 源
默认情况下,Kubernetes 使用 kubelet 内运行的嵌入式 cAdvisor
获取节点概要指标数据。如果你在自己的集群中启用 PodAndContainerStatsFromCRI
特性门控,
且你通过容器运行时接口(CRI)使用支持统计访问的容器运行时,
则 kubelet 将使用 CRI 来获取 Pod 和容器级别的指标数据,
而不是 cAdvisor 来获取。
压力停滞信息(PSI)
Kubernetes v1.34 [beta]
作为 Beta 级别特性,Kubernetes 允许你配置 kubelet 来收集 Linux
内核的压力停滞信息(PSI)
的 CPU、内存和 I/O 使用情况。这些信息是在节点、Pod 和容器级别上收集的。
详细模式请参见 Summary API。
此特性默认启用,通过 KubeletPSI
特性门控管理。
这些信息也在
Prometheus 指标中暴露。
参见了解 PSI 指标, 学习如何解读 PSI 指标。
要求
压力停滞信息要求:
接下来
集群故障排查任务页面讨论了如何使用依赖这些数据的指标管道。
4 - 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_histograms 和 always_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: true 但
always_scrape_classic_histograms: false(默认值),Prometheus 仅摄入原生直方图。
使用经典直方图查询的现有仪表板(例如 histogram_quantile(..._bucket...))将不显示数据。
在迁移期间始终将 always_scrape_classic_histograms: true 设置为 true。
从经典直方图查询迁移到原生直方图查询时,请遵循此工作流程:
- 启用两种格式:在你的 Prometheus 抓取配置中设置
scrape_native_histograms: true和always_scrape_classic_histograms: true。
-
迁移查询:将仪表板查询和告警表达式从经典直方图函数更新为原生直方图等效函数。
经典查询:
histogram_quantile(0.99, rate(apiserver_request_duration_seconds_bucket[5m]))原生直方图查询:
histogram_quantile(0.99, rate(apiserver_request_duration_seconds[5m]))
- 在预发布环境中验证:在推送到生产环境之前,使用原生直方图查询测试所有仪表板和告警。
- 禁用经典抓取:迁移完成并验证后,设置
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: true但always_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响应应包含直方图指标的原生地直方图编码。
参考
- 阅读 Prometheus 原生直方图文档 以了解原生直方图格式和查询函数的详细信息。
- 查看 Kubernetes 指标参考以获取 Kubernetes 组件暴露的指标完整列表。
5 - Kubernetes z-pages
Kubernetes v1.32 [alpha]
Kubernetes 的核心组件可以暴露一系列 z-endpoints,以便用户更轻松地调试他们的集群及其组件。 这些端点仅用于人工检查,以获取组件二进制文件的实时调试信息。请不要自动抓取这些端点返回的数据; 在 Kubernetes 1.36 中,这些是 Alpha 特性,响应格式可能会在未来版本中发生变化。
z-pages
Kubernetes v1.36 允许你启用 z-pages 来帮助排查其核心控制平面组件的问题。 这些特殊的调试端点提供与正在运行的组件有关的内部信息。对于 Kubernetes 1.36, 这些组件提供以下端点(当启用 z-pages 后):
statusz
使用 ComponentStatusz
特性门控启用后,
/statusz 端点显示有关组件的高级信息,例如其 Kubernetes 版本、仿真版本、启动时间等。
来自 API 服务器的 /statusz 纯文本响应类似于:
kube-apiserver statusz
Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only.
Started: Wed Oct 16 21:03:43 UTC 2024
Up: 0 hr 00 min 16 sec
Go version: go1.23.2
Binary version: 1.32.0-alpha.0.1484+5eeac4f21a491b-dirty
Emulation version: 1.32.0-alpha.0.1484
Paths: /healthz /livez /metrics /readyz /statusz /version
statusz(结构化的)
Kubernetes v1.36 [beta](默认启用)从 Kubernetes v1.35 开始,/statusz 端点支持结构化的、版本化的响应格式,
前提是请求时使用了正确的 Accept 标头。
如果没有 Accept 标头,则该端点默认返回纯文本响应格式。
如需获取结构化回复,请使用:
Accept: application/json;v=v1alpha1;g=config.k8s.io;as=Statusz
说明:
如果你请求 application/json 时未指定所有必需参数(g、v 和 as),
服务器将响应 406 Not Acceptable。
结构化响应示例:
{
"kind": "Statusz",
"apiVersion": "config.k8s.io/v1alpha1",
"metadata": {
"name": "kube-apiserver"
},
"startTime": "2025-10-29T00:30:01Z",
"uptimeSeconds": 856,
"goVersion": "go1.23.2",
"binaryVersion": "1.35.0",
"emulationVersion": "1.35",
"paths": [
"/healthz",
"/livez",
"/metrics",
"/readyz",
"/statusz",
"/version"
]
}
结构化 /statusz 响应的 config.k8s.io/v1alpha1 模式如下:
// Statusz is the config.k8s.io/v1alpha1 schema for the /statusz endpoint.
type Statusz struct {
// Kind is "Statusz".
Kind string `json:"kind"`
// APIVersion is the version of the object, e.g., "config.k8s.io/v1alpha1".
APIVersion string `json:"apiVersion"`
// Standard object's metadata.
// +optional
Metadata metav1.ObjectMeta `json:"metadata,omitempty"`
// StartTime is the time the component process was initiated.
StartTime metav1.Time `json:"startTime"`
// UptimeSeconds is the duration in seconds for which the component has been running continuously.
UptimeSeconds int64 `json:"uptimeSeconds"`
// GoVersion is the version of the Go programming language used to build the binary.
// The format is not guaranteed to be consistent across different Go builds.
// +optional
GoVersion string `json:"goVersion,omitempty"`
// BinaryVersion is the version of the component's binary.
// The format is not guaranteed to be semantic versioning and may be an arbitrary string.
BinaryVersion string `json:"binaryVersion"`
// EmulationVersion is the Kubernetes API version which this component is emulating.
// if present, formatted as "<major>.<minor>"
// +optional
EmulationVersion string `json:"emulationVersion,omitempty"`
// MinimumCompatibilityVersion is the minimum Kubernetes API version with which the component is designed to work.
// if present, formatted as "<major>.<minor>"
// +optional
MinimumCompatibilityVersion string `json:"minimumCompatibilityVersion,omitempty"`
// Paths contains relative URLs to other essential read-only endpoints for debugging and troubleshooting.
// +optional
Paths []string `json:"paths,omitempty"`
}
flagz
使用 ComponentFlagz
特性门控启用后,
/flagz 端点为你显示用于启动某组件的命令行参数。
API 服务器的 /flagz 纯文本响应看起来类似于:
kube-apiserver flags
Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only.
advertise-address=192.168.8.2
contention-profiling=false
enable-priority-and-fairness=true
profiling=true
authorization-mode=[Node,RBAC]
authorization-webhook-cache-authorized-ttl=5m0s
authorization-webhook-cache-unauthorized-ttl=30s
authorization-webhook-version=v1beta1
default-watch-cache-size=100
flagz (structured)
Kubernetes v1.36 [beta](默认启用)从 Kubernetes v1.35 开始,/flagz 端点支持结构化、版本化的响应格式,
前提是请求时使用了正确的 Accept 标头。
如果没有 Accept 标头,则该端点默认返回纯文本响应格式。
要请求结构化响应,请使用:
Accept: application/json;v=v1alpha1;g=config.k8s.io;as=Flagz
说明:
如果你请求 application/json 时未指定所有必需参数(g、v 和 as),
服务器将响应 406 Not Acceptable。
Example structured response:
{
"kind": "Flagz",
"apiVersion": "config.k8s.io/v1alpha1",
"metadata": {
"name": "kube-apiserver"
},
"flags": {
"advertise-address": "192.168.8.4",
"allow-privileged": "true",
"anonymous-auth": "true",
"authorization-mode": "[Node,RBAC]",
"enable-priority-and-fairness": "true",
"profiling": "true",
"default-watch-cache-size": "100"
}
}
The config.k8s.io/v1alpha1 schema for the structured /flagz response is as follows:
// Flagz is the config.k8s.io/v1alpha1 schema for the /flagz endpoint.
type Flagz struct {
// Kind is "Flagz".
Kind string `json:"kind"`
// APIVersion is the version of the object, e.g., "config.k8s.io/v1alpha1".
APIVersion string `json:"apiVersion"`
// Standard object's metadata.
// +optional
Metadata metav1.ObjectMeta `json:"metadata,omitempty"`
// Flags contains the command-line flags and their values.
// The keys are the flag names and the values are the flag values,
// possibly with confidential values redacted.
// +optional
Flags map[string]string `json:"flags,omitempty"`
}
说明:
/statusz 和 /flagz 的结构化响应在 v1.35 版本中仍处于 Alpha 阶段,未来版本可能会有所更改。
它们旨在为调试和自省工具提供机器可解析的输出。