Kubernetes 系统组件的度量指标

系统组件指标可以更深入地了解组件内部发生的情况。指标对于构建仪表板和告警尤为有用。

Kubernetes 组件以 Prometheus 格式发出指标。这种格式是结构化的纯文本,旨在让人员和机器都能阅读。

Kubernetes 中的指标

在大多数情况下,指标可在 HTTP 服务器的 /metrics 端点上获得。对于默认不暴露该端点的组件,可以使用 --bind-address 标志启用它。

这些组件的示例

在生产环境中,您可能希望配置 Prometheus Server 或其他指标抓取工具,定期收集这些指标并使其在某种时间序列数据库中可用。

请注意,kubelet 还在 /metrics/cadvisor/metrics/resource/metrics/probes 端点上暴露指标。这些指标的生命周期不同。

如果您的集群使用 RBAC,读取指标需要通过用户、组或 ServiceAccount 进行授权,并具有允许访问 /metrics 的 ClusterRole。例如

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
  - nonResourceURLs:
      - "/metrics"
    verbs:
      - get

指标生命周期

Alpha 指标 → Beta 指标 → 稳定指标 → 已弃用指标 → 隐藏指标 → 已删除指标

Alpha 指标没有稳定性保证。这些指标随时可能被修改或删除。

Beta 指标遵守比稳定指标更宽松的 API 契约。在 Beta 指标的生命周期内,不能删除任何标签,但可以在指标处于 Beta 阶段时添加标签。

稳定指标保证不会改变。这意味着

  • 没有弃用签名的稳定指标不会被删除或重命名
  • 稳定指标的类型不会被修改

已弃用的指标计划删除,但仍可使用。这些指标包含有关其被弃用版本的注释。

例如

  • 弃用前

    # HELP some_counter this counts things
    # TYPE some_counter counter
    some_counter 0
    
  • 弃用后

    # HELP some_counter (Deprecated since 1.15.0) this counts things
    # TYPE some_counter counter
    some_counter 0
    

隐藏指标不再发布以供抓取,但仍可使用。基于其稳定性级别,已弃用的指标在一段时间后会变成隐藏指标

  • 稳定 (STABLE) 指标在至少 3 个发行版或 9 个月后(以较长者为准)变为隐藏。
  • BETA 指标在至少 1 个发行版或 4 个月后(以较长者为准)变为隐藏。
  • ALPHA 指标可以在被弃用的同一个发行版中被隐藏或移除。

要使用隐藏指标,必须启用它。有关详细信息,请参阅显示隐藏指标部分。

已删除的指标不再发布,也无法使用。

显示隐藏指标

如上所述,管理员可以通过特定二进制文件上的命令行标志启用隐藏指标。这旨在作为管理员的“逃生舱”,以防他们错过了上个版本中已弃用指标的迁移。

标志 show-hidden-metrics-for-version 接收一个版本号,用于显示在该版本中被弃用的指标。版本表示为 x.y,其中 x 是主版本号,y 是次版本号。即使指标可以在补丁版本中被弃用,也不需要补丁版本号,这是因为指标弃用策略是针对次版本发布的。

该标志只能将上一个次版本作为其值。如果您想显示上一个版本中隐藏的所有指标,可以将 show-hidden-metrics-for-version 标志设置为上一个版本。使用太旧的版本是不允许的,因为它违反了指标弃用策略。

例如,假设指标 A1.29 中被弃用。指标 A 变为隐藏的版本取决于其稳定性级别

  • 如果指标 AALPHA,它可能在 1.29 中被隐藏。
  • 如果指标 ABETA,它最早会在 1.30 中被隐藏。如果您正在升级到 1.30 并且仍然需要 A,则必须使用命令行标志 --show-hidden-metrics-for-version=1.29
  • 如果指标 ASTABLE,它最早会在 1.32 中被隐藏。如果您正在升级到 1.32 并且仍然需要 A,则必须使用命令行标志 --show-hidden-metrics-for-version=1.31

组件指标

kube-controller-manager 指标

控制器管理器指标提供了对控制器管理器性能和健康状况的重要洞察。这些指标包括常见的 Go 语言运行时指标(如 go_routine 计数)和特定于控制器的指标(如 etcd 请求延迟或可用于衡量集群健康状况的云厂商(AWS、GCE、OpenStack)API 延迟)。

从 Kubernetes 1.7 开始,可为 GCE、AWS、Vsphere 和 OpenStack 的存储操作提供详细的云厂商指标。这些指标可用于监控持久卷操作的健康状况。

例如,对于 GCE,这些指标被称为

cloudprovider_gce_api_request_duration_seconds { request = "instance_list"}
cloudprovider_gce_api_request_duration_seconds { request = "disk_insert"}
cloudprovider_gce_api_request_duration_seconds { request = "disk_delete"}
cloudprovider_gce_api_request_duration_seconds { request = "attach_disk"}
cloudprovider_gce_api_request_duration_seconds { request = "detach_disk"}
cloudprovider_gce_api_request_duration_seconds { request = "list_disk"}

kube-scheduler 指标

特性状态: Kubernetes v1.21 [beta]

调度程序公开了可选指标,报告所有运行中 Pod 的已请求资源和期望限制。这些指标可用于构建容量规划仪表板,评估当前或历史调度限制,快速识别因资源不足而无法调度的负载,并将实际用量与 Pod 的请求进行比较。

kube-scheduler 会标识为每个 Pod 配置的资源请求和限制;当请求或限制非零时,kube-scheduler 会报告指标时间序列。该时间序列由以下内容标记

  • 命名空间
  • pod 名称
  • Pod 调度的节点,如果尚未调度则为空字符串
  • 优先级
  • 该 Pod 指定的调度程序
  • 资源名称(例如,cpu
  • 资源单位(如果已知)(例如,cores

一旦 Pod 完成(restartPolicyNeverOnFailure,且 Pod 阶段为 SucceededFailed,或者已被删除且所有容器处于终止状态),该系列将不再报告,因为调度程序现在可以自由调度其他 Pod 运行。这两个指标分别称为 kube_pod_resource_requestkube_pod_resource_limit

这些指标在 HTTP 端点 /metrics/resources 上公开。它们需要 /metrics/resources 端点的授权,通常通过具有针对 /metrics/resources 非资源 URL 的 get 动词的 ClusterRole 来授予。

在 Kubernetes 1.21 上,您必须使用 --show-hidden-metrics-for-version=1.20 标志来暴露这些 alpha 稳定性指标。

kubelet 压力失速信息 (PSI) 指标

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

当内核启用了 PSI(版本 4.20 或更高)时,kubelet 会收集 CPU、内存和 I/O 使用的压力失速信息 (Pressure Stall Information, PSI)。该信息在节点、Pod 和容器级别收集。

Prometheus 指标:在 /metrics/cadvisor 端点上公开为累积计数器(总计),表示总失速时间(以秒为单位)。指标以此端点公开,具有以下名称

container_pressure_cpu_stalled_seconds_total
container_pressure_cpu_waiting_seconds_total
container_pressure_memory_stalled_seconds_total
container_pressure_memory_waiting_seconds_total
container_pressure_io_stalled_seconds_total
container_pressure_io_waiting_seconds_total

摘要 API:在 /stats/summary 端点上公开,提供 JSON 格式的累积 totals 和移动平均值(avg10avg60avg300)。这些平均值表示任务在资源上失速的时间百分比,分别对应 10 秒、60 秒和 5 分钟的间隔。

这些指标也通过节点在 /proc/pressure/ 中的相应文件(cpu、memory 和 io)以以下格式原生导出

some avg10=0.00 avg60=0.00 avg300=0.00 total=0
full avg10=0.00 avg60=0.00 avg300=0.00 total=0

如何将这些指标结合起来解释?以来自摘要 API 的以下查询为例
kubectl get --raw "/api/v1/nodes/$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')/proxy/stats/summary" | jq '.pods[].containers[] | select(.name=="<CONTAINER_NAME>") | {name, cpu: .cpu.psi, memory: .memory.psi, io: .io.psi}'。这会以 json 格式返回以下信息。

{
  "name": "<CONTAINER_NAME>",
  "cpu": {
    "full": {
      "total": 0,
      "avg10": 0,
      "avg60": 0,
      "avg300": 0
    },
    "some": {
      "total": 35232438,
      "avg10": 0.74,
      "avg60": 0.52,
      "avg300": 0.21,
    },  
  },
  "memory": {
    "full": {
      "total": 539105,
      "avg10": 0,
      "avg60": 0,
      "avg300": 0
    },
    "some": {
      "total": 658164,
      "avg10": 0.01,
      "avg60": 0.01,
      "avg300": 0.00,
    },
    }
  },
  "io": {
    "full": {
      "total": 33190987,
      "avg10": 0.31,
      "avg60": 0.22,
      "avg300": 0.05,
    },
    "some": {
      "total": 40809937,
      "avg10": 0.52,
      "avg60": 0.45,
      "avg300": 0.12,
    }
  }
}

这是一个简单的尖峰场景。cpu.some 的 avg10 值为 0.74,表示在过去 10 秒内,该容器中至少有一个任务因 CPU 而失速了 0.74% 的时间(0.0074 秒或 74 毫秒)。由于同一资源上的 avg10 (0.74) 明显高于 avg300 (0.21),这表明近期资源争用激增,而不是持续的长期瓶颈。如果持续监控并且 avg300 指标也增加,我们就可以诊断出更严重、持久的问题!

此外,请注意在此示例中 cpu.some 如何显示压力,而 cpu.full 保持在 0.00。这告诉我们,虽然一些进程在等待 CPU 时间时被延迟,但容器作为一个整体仍在取得进展。非零的 full 值将表明所有非空闲任务同时失速,这是一个更严重的问题。尽管 total 值 35232438 不太易于阅读,但它代表了以微秒为单位的累积失速时间,这允许检测在平均值中可能无法显示的延迟尖峰。它们对于像 Prometheus 这样的监控系统也非常有用,可以计算特定时间窗口内的精确增加率。最后,当观察到高 I/O 压力同时伴随低内存压力时,这可能表明应用程序正在等待磁盘吞吐量,而不是因为缺乏可用 RAM 而失败。节点的内存没有超额承诺,可以调查磁盘消耗的其他诊断方案。

PSI 指标解锁了一种更稳健的方法来监控每个 cgroup 在各个级别的实时资源争用,为系统范围内的动态处理工作负载开辟了机会。您可以在 理解 PSI 指标 中阅读有关 PSI 指标的更多信息。

要求

压力失速信息需要

禁用指标

您可以通过命令行标志 --disabled-metrics 显式关闭指标。如果例如某个指标导致性能问题,这可能是所需要的。输入是已禁用指标的列表(例如 --disabled-metrics=metric1,metric2)。

指标基数强制执行

具有无界维度的指标可能会导致其检测组件中的内存问题。为了限制资源使用,您可以使用 --allow-metric-labels 命令行选项动态配置指标的标签值允许列表。

在 alpha 阶段,该标志只能接受一系列映射作为指标标签允许列表。每个映射的格式为 <metric_name>,<label_name>=<allowed_labels>,其中 <allowed_labels> 是逗号分隔的可接受标签名称列表。

整体格式如下

--allow-metric-labels <metric_name>,<label_name>='<allow_value1>, <allow_value2>...', <metric_name2>,<label_name>='<allow_value1>, <allow_value2>...', ...

这是一个示例

--allow-metric-labels number_count_metric,odd_number='1,3,5', number_count_metric,even_number='2,4,6', date_gauge_metric,weekend='Saturday,Sunday'

除了从 CLI 指定此操作外,也可以在配置文件中完成。您可以使用组件的 --allow-metric-labels-manifest 命令行参数指定该配置文件的路径。以下是该配置文件内容的示例

"metric1,label2": "v1,v2,v3"
"metric2,label1": "v1,v2,v3"

此外,cardinality_enforcement_unexpected_categorizations_total 元指标记录了基数强制执行期间意外分类的计数,即每当遇到相对于允许列表约束不被允许的标签值时。

接下来


最后修改于 2026 年 4 月 7 日 23:27 PST:根据反馈进行润色并添加示例 (47fac02a76)