kube-state-metrics Pod 指标详解:60 个 Pod 指标全集、Opt-in 机制与 Terminating/Unknown 状态查询实战
2026/9/17 11:13:23 网站建设 项目流程

kube-state-metrics Pod 指标详解:60 个 Pod 指标全集、Opt-in 机制与 Terminating/Unknown 状态查询实战

【免费下载链接】kube-state-metricsAdd-on agent to generate and expose cluster-level metrics.项目地址: https://gitcode.com/GitHub_Trending/ku/kube-state-metrics

kube-state-metrics 是 Kubernetes 生态中标准的集群对象指标采集器,其中 Pod 是暴露指标数量最多、与日常故障排查关联最紧密的资源类型。本文以仓库中 Pod 指标文档 为骨架,完整收录全部 60 个 Pod 指标(含类型、单位、标签与稳定性状态),并结合 internal/store/pod.go 的源码实现,深入讲解指标生成机制、--metric-labels-allowlist/--metric-annotations-allowlist/--metric-opt-in-list三类控制参数,以及用 PromQL 识别 "Terminating"、"Unknown" 这类非标准 Pod 状态并配置告警的完整实战方案。

1. 指标来源与整体约定

kube-state-metrics 通过 List/Watch 机制监听集群中的 Pod 对象(见 createPodListWatch,它构造cache.ListWatch并对List/Watch统一附加 fieldSelector),将每个 Pod 的 Spec 与 Status 字段转换为 Prometheus 指标后暴露在/metrics端点。所有 Pod 指标族在 podMetricFamilies 中集中注册,共 60 个指标族。

使用这些指标时需要理解四个通用约定:

  1. 默认标签:所有 Pod 指标都会携带namespacepoduid三个默认标签。这一行为由 wrapPodFunc 统一实现——它在每个指标生成后,把descPodLabelsDefaultLabels = []string{"namespace", "pod", "uid"}合并进每条 metric series 的标签中。
  2. 类型:绝大多数为 Gauge(值通常为 0/1 的状态位或时间戳),少数为 Counter(如kube_pod_container_status_restarts_total)。
  3. 稳定性状态(Status)STABLE表示指标语义已稳定;EXPERIMENTAL表示仍在演进,字段或标签可能变化。源码中对应basemetrics.STABLEbasemetrics.ALPHA稳定性级别,并以[STABLE]前缀写入 HELP 行。
  4. Opt-in 机制:标注 Opt-in 的指标默认不暴露,需通过--metric-opt-in-list启用。文档中唯一的 Opt-in 指标是kube_pod_nodeselectors,源码中它使用 NewOptInFamilyGenerator 注册。Opt-in 过滤逻辑位于 pkg/optin/optin.go:MetricFamilyFilter.Test--metric-opt-in-list中每一项编译为正则,只有匹配的 opt-in 指标族才放行,非 opt-in 指标族则始终返回 true。

关于 Pod 级资源 request/limit 的重要提示(原文档 Note 的完整继承):对于 Pod 资源请求与限制,kube-scheduler 在其/metrics/resources端点暴露的kube_pod_resource_requestkube_pod_resource_limit是基于 Pod 的有效资源需求计算的,已经考虑了 Pod 级资源(pod.spec.resources,自 Kubernetes 1.34 起 beta 并默认启用)。这些指标由 KEP-1748(Pod Resource Metrics)定义,官方推荐优先使用 kube-scheduler 的这两个指标,而非本文档中的容器级kube_pod_container_resource_requests/kube_pod_container_resource_limits。kube-state-metrics 本身不暴露独立的 Pod 级资源指标。这一点在源码中同样有印证:createPodContainerResourceLimitsFamilyGenerator 的 HELP 文本明确写着 "It is recommended to use the kube_pod_resource_limits metric exposed by kube-scheduler instead, as it is more precise."

2. Pod 指标全集

以下表格完整继承自 Pod 指标文档,按主题分组。"Opt-in" 列中 "Opt-in" 表示需--metric-opt-in-list显式启用。

2.1 Pod 基础信息与标识类

指标名类型说明单位标签状态Opt-in
kube_pod_annotationsGaugeKubernetes 注解转换为 Prometheus 标签,受--metric-annotations-allowlist(见命令行参数文档)控制-pod= ;namespace= ;annotation_POD_ANNOTATION=<POD_ANNOTATION>;uid=EXPERIMENTAL-
kube_pod_infoGaugePod 信息-podnamespacehost_ip= ;pod_ip= ;node= ;created_by_kindcreated_by_nameuidpriority_class=<priority_class>;host_network=<true/false>STABLE-
kube_pod_ipsGaugePod IP 地址(每 IP 一条 series)-podnamespaceip= ;ip_family=<4 或 6>;uidEXPERIMENTAL-
kube_pod_start_timeGaugePod 启动时间(Unix 时间戳)podnamespaceuidSTABLE-
kube_pod_completion_timeGaugePod 完成时间(Unix 时间戳)podnamespaceuidSTABLE-
kube_pod_ownerGaugePod 的属主信息-podnamespaceowner_kindowner_nameowner_is_controlleruidSTABLE-
kube_pod_labelsGaugeKubernetes 标签转换为 Prometheus 标签,受--metric-labels-allowlist(见命令行参数文档)控制-podnamespacelabel_POD_LABEL=<POD_LABEL>;uidSTABLE-
kube_pod_nodeselectorsGauge描述 Pod 的 nodeSelectors-podnamespacenodeselector_NODE_SELECTOR=<NODE_SELECTOR>;uidEXPERIMENTALOpt-in
kube_pod_createdGaugePod 创建 Unix 时间戳podnamespaceuidSTABLE-
kube_pod_deletion_timestampGaugePod 删除 Unix 时间戳podnamespaceuidEXPERIMENTAL-
kube_pod_restart_policyGaugePod 使用的重启策略-podnamespacetype=<Always|Never|OnFailure>;uidSTABLE-
kube_pod_runtimeclass_name_infoGaugePod 关联的 RuntimeClass-podnamespaceuidEXPERIMENTAL-
kube_pod_service_accountGaugePod 使用的 ServiceAccount-podnamespaceuidservice_accountEXPERIMENTAL-
kube_pod_schedulerGaugePod 使用的调度器-podnamespaceuidname=EXPERIMENTAL-
kube_pod_tolerationsGaugePod 容忍度信息-podnamespaceuidkeyoperatorvalueeffecttoleration_secondsEXPERIMENTAL-
kube_pod_resourceclaim_infoGaugePod 引用的 DRA ResourceClaim 信息,pod.spec.resourceClaims每个条目一条 series-podnamespaceuidclaim_name=<pod 局部引用名>;resourceclaim_name=<解析后的 ResourceClaim 名>;resourceclaim_template_nameEXPERIMENTAL-

实现细节补充(基于源码):

  • kube_pod_info的属主信息来自 createPodInfoFamilyGenerator,它调用metav1.GetControllerOf(p)提取 controller owner 的 Kind/Name,因此created_by_kind/created_by_name反映的是控制器(如 ReplicaSet、StatefulSet)而非任意 ownerReference。
  • kube_pod_ips在 createPodIPFamilyGenerator 中逐个解析status.podIPs,使用netip.ParseAddr校验并用Unmap()归一化 IPv4-mapped IPv6 地址,解析失败的 IP 会被跳过而不进入指标序列。
  • kube_pod_tolerations在 createPodTolerationsFamilyGenerator 中先经过 getUniqueTolerations 按 (key, operator, value, effect, tolerationSeconds) 五元组去重——因为v1.Toleration含指针字段TolerationSeconds,不能直接做结构体比较,故源码构造了独立身份键去重。
  • kube_pod_resourceclaim_info(createPodResourceClaimInfoFamilyGenerator)对模板型 claim 会从pod.status.resourceClaimStatuses中回填 kubelet 解析出的真实 ResourceClaim 名称;claim 尚在创建中时resourceclaim_name为空。

2.2 Pod 状态与 Phase 类

指标名类型说明单位标签状态Opt-in
kube_pod_status_phaseGaugePod 当前 phase-podnamespacephase=<Pending|Running|Succeeded|Failed|Unknown>;uidSTABLE-
kube_pod_status_qos_classGaugePod 当前 QoS Class-podnamespaceqos_class=<BestEffort|Burstable|Guaranteed>;uidEXPERIMENTAL-
kube_pod_status_readyGaugePod 是否就绪可服务请求-podnamespacecondition=<true|false|unknown>;uidSTABLE-
kube_pod_status_scheduledGaugePod 调度过程状态-podnamespacecondition=<true|false|unknown>;uidSTABLE-
kube_pod_status_initialized_timeGaugePod 完成初始化时间podnamespaceuidEXPERIMENTAL-
kube_pod_status_ready_timeGaugePod 通过就绪探针时间podnamespaceuidEXPERIMENTAL-
kube_pod_status_container_ready_timeGaugePod 容器进入 Ready 状态时间podnamespaceuidEXPERIMENTAL-
kube_pod_status_reasonGaugePod 状态原因。仅对实际设置的原因输出 series,series 缺失不代表原因为否;未识别的pod.status.reason报告为Other;不在此列表中的 conditions / container-terminated 原因不报告-podnamespacereason=<Evicted|NodeAffinity|NodeLost|PreemptionByScheduler|SchedulingGated|Shutdown|TerminationByKubelet|UnexpectedAdmissionError|Other>;uidEXPERIMENTAL-
kube_pod_status_disruption_reasonGaugePod 中断条件(DisruptionTarget condition)原因。仅当存在DisruptionTargetcondition 时输出,series 缺失不代表原因不存在;未识别原因报告为Otherkube_pod_status_reason独立保留,已有的针对它的查询不应被此指标替换-podnamespacereason=<PreemptionByScheduler|DeletionByTaintManager|EvictionByEvictionAPI|DeletionByPodGC|TerminationByKubelet|Other>;uidEXPERIMENTAL-
kube_pod_status_scheduled_timeGaugePod 进入已调度状态的 Unix 时间戳podnamespaceuidSTABLE-
kube_pod_status_unschedulableGaugePod 不可调度状态-podnamespaceuidSTABLE-
kube_pod_status_unscheduled_timeGaugePod 进入不可调度状态的 Unix 时间戳podnamespaceuidEXPERIMENTAL-

源码级解析(这是理解这两个 reason 指标的关键):

  • kube_pod_status_reason的候选原因白名单硬编码在 podStatusReasons:{"Evicted", "NodeAffinity", "NodeLost", "PreemptionByScheduler", "SchedulingGated", "Shutdown", "TerminationByKubelet", "UnexpectedAdmissionError"}。判定逻辑 hasPodStatusReason 依次检查三处:pod.status.reasonstatus.conditions[*].reasonstatus.containerStatuses[*].state.terminated.reason,任一处命中即输出reason=<原因>的 series;若pod.status.reason非空但不在白名单内,则输出reason="Other"(见 createPodStatusReasonFamilyGenerator)。
  • kube_pod_status_disruption_reason(createPodStatusDisruptionReasonFamilyGenerator)只扫描类型为DisruptionTarget的 condition,其白名单podDisruptionConditionReasons{PreemptionByScheduler, DeletionByTaintManager, EvictionByEvictionAPI, DeletionByPodGC, TerminationByKubelet},未命中归入Other
  • internal/store/pod_test.go 中有对应的测试用例验证上述行为:例如 Pod Reason 为NodeLost时输出kube_pod_status_reason{reason="NodeLost"} 1(测试样例);DisruptionTargetcondition 携带未知原因SomeFutureReason时输出reason="Other"(测试样例);非DisruptionTarget类型的 condition(如PodReady上带 reason)不产生任何 disruption series(测试样例)。
  • kube_pod_status_scheduled/kube_pod_status_scheduled_time/kube_pod_status_unschedulable/kube_pod_status_unscheduled_time全部派生自PodScheduledcondition(createPodStatusScheduledTimeFamilyGenerator 等):condition=true时用lastTransitionTime输出 scheduled_time 时间戳;condition=false时输出 unschedulable=1 与 unscheduled_time。

2.3 容器(Container)状态类

指标名类型说明单位标签状态Opt-in
kube_pod_container_infoGaugePod 中容器的信息-containerpodnamespaceimageimage_idimage_speccontainer_iduidSTABLE-
kube_pod_container_status_waitingGauge容器是否处于 waiting 状态-containerpodnamespaceuidSTABLE-
kube_pod_container_status_waiting_reasonGauge容器处于 waiting 状态的原因-containerpodnamespacereasonuidSTABLE-
kube_pod_container_status_runningGauge容器是否处于 running 状态-containerpodnamespaceuidSTABLE-
kube_pod_container_state_startedGaugePod 容器的启动时间(Unix 时间戳)containerpodnamespaceuidSTABLE-
kube_pod_container_status_terminatedGauge容器是否处于 terminated 状态-containerpodnamespaceuidSTABLE-
kube_pod_container_status_terminated_reasonGauge容器当前处于 terminated 状态的原因-containerpodnamespacereasonuidEXPERIMENTAL-
kube_pod_container_status_last_terminated_reasonGauge容器上一次处于 terminated 状态的原因-containerpodnamespacereasonuidEXPERIMENTAL-
kube_pod_container_status_last_terminated_exitcodeGauge上一次处于 terminated 状态容器的退出码-containerpodnamespaceuidEXPERIMENTAL-
kube_pod_container_status_last_terminated_timestampGaugePod 容器最后一次终止的 Unix 时间戳-containerpodnamespaceuidEXPERIMENTAL-
kube_pod_container_status_readyGauge容器就绪检查是否成功-containerpodnamespaceuidSTABLE-
kube_pod_container_status_restarts_totalCounter每个容器的重启次数-containernamespacepoduidSTABLE-

源码补充:createPodContainerInfoFamilyGenerator 中kube_pod_container_info的标签同时携带"声明镜像"(spec.containers[].image,即image_spec)与"实际运行镜像"(status.containerStatuses[].image,即image)和image_id,便于做镜像漂移/灰度对比。createPodContainerStateStartedFamilyGenerator 在容器 Running 时取state.running.startedAt,容器已 Terminated 时回退取state.terminated.startedAt,保证重启后仍有启动时间序列。

2.4 Init 容器状态类

指标名类型说明单位标签状态Opt-in
kube_pod_init_container_infoGaugePod 中 init 容器的信息-containerpodnamespaceimageimage_idimage_speccontainer_iduidrestart_policySTABLE-
kube_pod_init_container_state_startedGaugePod init 容器的启动时间(Unix 时间戳)containerpodnamespaceuidEXPERIMENTAL-
kube_pod_init_container_status_waitingGaugeinit 容器是否处于 waiting 状态-containerpodnamespaceuidSTABLE-
kube_pod_init_container_status_waiting_reasonGaugeinit 容器处于 waiting 状态的原因-containerpodnamespacereasonuidEXPERIMENTAL-
kube_pod_init_container_status_runningGaugeinit 容器是否处于 running 状态-containerpodnamespaceuidSTABLE-
kube_pod_init_container_status_terminatedGaugeinit 容器是否处于 terminated 状态-containerpodnamespaceuidSTABLE-
kube_pod_init_container_status_terminated_reasonGaugeinit 容器处于 terminated 状态的原因-containerpodnamespacereasonuidEXPERIMENTAL-
kube_pod_init_container_status_last_terminated_reasonGaugeinit 容器上一次处于 terminated 状态的原因-containerpodnamespacereasonuidEXPERIMENTAL-
kube_pod_init_container_status_last_terminated_exitcodeGauge上一次处于 terminated 状态 init 容器的退出码-containerpodnamespaceuidEXPERIMENTAL-
kube_pod_init_container_status_last_terminated_timestampGaugePod init 容器最后一次终止的 Unix 时间戳containerpodnamespaceuidEXPERIMENTAL-
kube_pod_init_container_status_readyGaugeinit 容器就绪检查是否成功-containerpodnamespaceuidSTABLE-
kube_pod_init_container_status_restarts_totalCounterinit 容器重启次数-containernamespacepoduidSTABLE-

与 2.3 的容器类指标一一对应。注意 createPodInitContainerInfoFamilyGenerator 额外输出restart_policy标签(对应 sidecar 容器 GA 后的restartPolicy: Always),而普通容器 info 指标没有该标签。

2.5 资源请求/限制与 Pod Overhead 类

指标名类型说明单位标签状态Opt-in
kube_pod_container_resource_requestsGauge容器请求的资源量。推荐改用 kube-scheduler 暴露的kube_pod_resource_request,其更精确cpu=核心数;memory=字节resourceunitcontainerpodnamespacenodeuidSTABLE-
kube_pod_container_resource_limitsGauge容器限制的资源量。推荐改用 kube-scheduler 暴露的kube_pod_resource_limit,其更精确cpu=核心数;memory=字节resourceunitcontainerpodnamespacenodeuidSTABLE-
kube_pod_init_container_resource_limitsGaugeinit 容器限制的资源量(如 CPU 核心数)cpu=核心数;memory=字节resourceunitcontainerpodnamespacenodeuidEXPERIMENTAL-
kube_pod_init_container_resource_requestsGaugeinit 容器请求的资源量(如 CPU 核心数)cpu=核心数;memory=字节resourceunitcontainerpodnamespacenodeuidEXPERIMENTAL-
kube_pod_overhead_cpu_coresGauge运行该 Pod 产生的 CPU overhead核心podnamespaceuidEXPERIMENTAL-
kube_pod_overhead_memory_bytesGauge运行该 Pod 产生的内存 overhead字节podnamespaceuidEXPERIMENTAL-

资源类指标的实现细节(以 createPodContainerResourceRequestsFamilyGenerator 为代表):

  • CPUconvertValueToFloat64转换为浮点核心数,unit标签为core
  • memory / storage / ephemeral-storageval.Value()取整数原始值(字节),unitbyte
  • hugepages 类资源按字节输出,可挂载卷扩展资源(如cdi.device/kubevirt.io*)按字节、其他扩展资源按整数输出——unit标签因此区分core/byte/integer,常量定义在 pkg/constant/resource_unit.go;
  • 标签中的node取自pod.spec.nodeName,Pod 未调度时为空串。

2.6 存储卷(PVC)类

指标名类型说明单位标签状态Opt-in
kube_pod_spec_volumes_persistentvolumeclaims_infoGaugePod 中 PVC 与 ephemeral 卷的信息。ephemeral="true"persistentvolumeclaim标签为生成的 claim 名<pod-name>-<volume-name>;非 ephemeral 卷保留声明的 claim 名-podnamespacevolumepersistentvolumeclaimephemeral=<true|false>;uidSTABLE-
kube_pod_spec_volumes_persistentvolumeclaims_readonlyGaugePVC 是否以只读方式挂载。Ephemeral 卷恒为 0(ephemeral volume source 不支持只读标志)。ephemeral 命名规则同上布尔podnamespacevolumepersistentvolumeclaimephemeral=<true|false>;uidSTABLE-

3. 通过 Allowlist 控制标签类指标的基数

kube_pod_labelskube_pod_annotations是把对象元数据"提升"为 Prometheus 标签的指标,标签基数可能爆炸,因此默认不暴露任何标签内容,需要显式通过命令行参数开启。参数语义(来自 cli-arguments.md):

# 允许将 pods 的 app 标签、namespaces 的某个标签转换为指标标签 --metric-labels-allowlist '=pods=[app],namespaces=[kubernetes.io/team]' # 允许 pods 的全部注解(性能影响严重,谨慎使用;'*' 必须是列表中第一项才生效) --metric-annotations-allowlist '=pods=[*]'

要点(继承自官方参数文档):资源名用复数形式;每个资源可提供一个*通配符放开全部 key,但文档明确警告其"有严重的性能影响";*作为列表首项才有效,出现在其他位置的*会被忽略;也可对资源维度提供*表示解析到所有资源。参数解析与白名单匹配逻辑位于 pkg/allowdenylist 与 pkg/metric_generator/filter.go。

--metric-opt-in-list用于放开 opt-in 指标族(当前 Pod 域仅kube_pod_nodeselectors),其值支持正则,由 pkg/optin 的MetricFamilyFilter逐族匹配。

4. 实战:识别 Terminating / Unknown 等非标准 Pod 状态

这是原文档 "Useful metrics queries" 章节的核心内容,完整继承如下。

TerminatingUnknown等状态不存在于Pod.Status的任何单一字段中phase只可能是 Pending/Running/Succeeded/Failed/Unknown 之一,而Terminatingkubectl get pod展示层的合成状态)。因此要模仿kubectl的展示逻辑,需要组合多个指标。

4.1 查询 Unknown 状态的 Pod

sum(kube_pod_status_phase{phase="Unknown"}) by (namespace, pod) or (count(kube_pod_deletion_timestamp) by (namespace, pod) * sum(kube_pod_status_reason{reason="NodeLost"}) by (namespace, pod))

语义:phase 已经是Unknown的 Pod,或"有删除时间戳 + status reason 为NodeLost(节点失联)"的 Pod,在kubectl中都会显示为Unknown

4.2 查询 Terminating 状态的 Pod

count(kube_pod_deletion_timestamp) by (namespace, pod) unless count(kube_pod_status_reason{reason="NodeLost"}) by (namespace, pod)

语义:设置了metadata.deletionTimestamp(即正在被删除)但原因不是NodeLost的 Pod,即处于Terminating。排除NodeLost是因为节点失联导致的 Pod 被 kubectl 归类为Unknown而非Terminating

4.3 告警规则:Pod 卡在 Terminating 超过 5 分钟

原文档给出的完整 Prometheus rule 示例如下,可直接放入告警规则文件:

groups: - name: Pod state rules: - alert: PodsBlockedInTerminatingState expr: count(kube_pod_deletion_timestamp) by (namespace, pod) unless count(kube_pod_status_reason{reason="NodeLost"}) by (namespace, pod) for: 5m labels: severity: page annotations: summary: Pod {{$labels.namespace}}/{{$labels.pod}} blocked in Terminating state.

for: 5m保证只有持续卡住 5 分钟以上才触发页级告警,可有效过滤滚动更新等正常删除流程的瞬时 Terminating。

5. 使用建议与注意事项

  1. 资源计量优先用 kube-scheduler 指标:如第 1 节所述,容量规划类查询应使用 kube-scheduler/metrics/resourceskube_pod_resource_request/kube_pod_resource_limit;kube-state-metrics 的容器级 request/limit 指标适合做"逐容器明细"分析(如找出哪个容器声明了异常资源)。
  2. Other兜底值的含义kube_pod_status_reasonkube_pod_status_disruption_reason对未识别原因统一输出Other,两者都是 EXPERIMENTAL 且只输出"实际命中的" series——series 不存在 ≠ 原因为否,编写 PromQL 时不要对这类指标做or vector(0)式的补零假设。kube_pod_status_disruption_reasonkube_pod_status_reason是互补关系,官方明确提示既有查询不应被前者替换。
  3. 时间戳类指标的单位统一为秒kube_pod_createdkube_pod_start_timekube_pod_deletion_timestamp、各类*_time指标均为 Unix 秒级时间戳,适合计算持续时长,例如time() - kube_pod_deletion_timestamp衡量 Pod 已卡在 Terminating 多久。
  4. 稳定性分级要纳入选型:生产监控建议以 STABLE 指标为主(kube_pod_infokube_pod_status_phasekube_pod_status_readykube_pod_status_scheduledkube_pod_container_status_*等核心状态指标);EXPERIMENTAL 指标(kube_pod_status_reasonkube_pod_ipskube_pod_resourceclaim_info等)在升级前建议查阅 CHANGELOG.md 确认语义变化。
  5. 控制基数:启用 labels/annotations 指标前评估白名单范围;开启kube_pod_nodeselectors前通过--metric-opt-in-list显式列出,避免无意放量。

6. 小结

本文覆盖了 Pod 指标文档 的全部内容:60 个指标按基础信息、状态/Phase、容器、Init 容器、资源、存储卷六大主题完整成表,保留了每个指标的类型、单位、标签与稳定性状态;结合 internal/store/pod.go 源码验证了默认标签注入(wrapPodFunc)、reason 白名单与Other兜底、tolerations 去重、IP 解析等关键实现,并对照 internal/store/pod_test.go 的测试用例确认行为;同时给出了--metric-labels-allowlist--metric-annotations-allowlist--metric-opt-in-list三个参数的实操语义,以及识别 Terminating/Unknown 状态的两条核心 PromQL 与配套告警规则,可直接用于生产环境的 Pod 生命周期监控建设。

【免费下载链接】kube-state-metricsAdd-on agent to generate and expose cluster-level metrics.项目地址: https://gitcode.com/GitHub_Trending/ku/kube-state-metrics

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询