4. 资源画像数据采集:Prometheus 指标采集、cAdvisor 数据、kube-state-metrics 数据源

资源画像的准确性直接决定成本分摊模型的公平性与可审计性。在云原生环境中,画像数据并非由单一工具提供,而是由 Prometheus 作为统一采集层,聚合 cAdvisor(容器级资源使用)与 kube-state-metrics(资源对象元数据与状态)两类核心数据源。本章将深入剖析这三者的协作机制、关键指标清单及常见采集故障的排查路径。

核心原则:资源画像 = 容器实时用量(cAdvisor) + 资源对象归属(kube-state-metrics) + 时间序列聚合(Prometheus)。三者缺一不可,任何一环的缺失或错乱都会导致分摊模型出现“幽灵成本”或“归属黑洞”。

4.1 数据采集架构总览

下图展示了资源画像数据采集的端到端链路:从容器运行时到 Prometheus 存储,再到成本分摊引擎的消费接口。

资源画像数据采集架构 资源画像数据采集架构 cAdvisor 容器 CPU / 内存 / 网络 / 磁盘 kube-state-metrics Pod / Deployment / Namespace 状态 Node Exporter 节点级资源总量 Prometheus Server 指标抓取 / relabel / 存储 / 查询 成本分摊引擎 / 资源画像服务 PromQL 查询 → 资源画像 → 成本分摊 关键链路:cAdvisor 提供容器实时用量,kube-state-metrics 提供归属标签,Prometheus 完成时间序列关联

4.2 cAdvisor:容器级资源使用数据

cAdvisor(Container Advisor)内嵌于 kubelet 中,负责采集每个 Pod 内所有容器的实时资源使用数据。它是资源画像中最细粒度的数据源,直接反映容器实际消耗的 CPU、内存、网络和磁盘 IO。

4.2.1 核心指标清单

指标名称 类型 说明 用于画像的典型 PromQL
container_cpu_usage_seconds_total Counter 容器累计 CPU 使用时间(秒) rate(container_cpu_usage_seconds_total[5m])
container_memory_working_set_bytes Gauge 容器当前工作集内存(字节) container_memory_working_set_bytes
container_network_receive_bytes_total Counter 容器网络接收字节累计 rate(container_network_receive_bytes_total[5m])
container_network_transmit_bytes_total Counter 容器网络发送字节累计 rate(container_network_transmit_bytes_total[5m])
container_fs_usage_bytes Gauge 容器根文件系统使用量 container_fs_usage_bytes
排查要点:如果 container_cpu_usage_seconds_total 长时间为 0 或缺失,请检查 kubelet 是否启用了 cAdvisor(默认开启),以及 Prometheus 的 scrape_config 中是否配置了 /metrics/cadvisor 端点。

4.2.2 常见采集故障与排查

  • 指标缺失:检查 kubelet 版本(v1.20+ 需显式启用 --feature-gates=PodAndContainerStatsFromCRI=true)。
  • 高基数问题:cAdvisor 会为每个容器生成大量时间序列,建议在 Prometheus 中通过 drop 规则过滤非核心指标(如 container_fs_* 中的非必要维度)。
  • 标签不一致:cAdvisor 暴露的 container_label_* 可能与 kube-state-metrics 的 kube_pod_labels 不匹配,需通过 relabel_configs 统一标签命名。

4.3 kube-state-metrics:资源对象元数据与状态

kube-state-metrics(KSM)从 Kubernetes API Server 监听资源对象的变化,生成关于 Pod、Deployment、Namespace、Node 等对象的元数据指标。在成本分摊模型中,KSM 提供“归属信息”——即哪个 Pod 属于哪个 Deployment、哪个 Namespace、哪个 Node。

4.3.1 核心指标清单

指标名称 说明 在画像中的用途
kube_pod_info Pod 基本信息(Node、UID、Host IP) 将容器用量关联到具体 Pod 和 Node
kube_pod_labels Pod 的标签(Label) 提取团队、环境、应用等成本归属维度
kube_pod_owner Pod 的 Owner 引用(Deployment/StatefulSet) 将 Pod 成本向上归集到工作负载
kube_namespace_labels Namespace 的标签 按业务线/项目维度分摊成本
kube_node_status_capacity Node 的资源容量 计算节点资源利用率与可分配比例

4.3.2 数据关联:cAdvisor × KSM

资源画像的核心操作是将 cAdvisor 的容器指标与 KSM 的元数据通过 pod 和 namespace 标签进行关联。典型的 PromQL 关联示例如下:

-- 获取每个 Pod 的 CPU 使用率(核数)
sum by (namespace, pod) (
  rate(container_cpu_usage_seconds_total{container!=""}[5m])
)
* on (namespace, pod) group_left(owner_name, owner_kind)
  kube_pod_owner

-- 获取每个 Deployment 的 CPU 使用总量
sum by (namespace, owner_name) (
  sum by (namespace, pod) (
    rate(container_cpu_usage_seconds_total{container!=""}[5m])
  )
  * on (namespace, pod) group_left(owner_name)
    kube_pod_owner{owner_kind="Deployment"}
)
常见故障:如果 kube_pod_owner 指标缺失,通常是因为 KSM 的 --metric-labels-allowlist 未包含 pods=[*],导致 Pod 标签未被采集。此时成本分摊将无法将 Pod 归集到上层工作负载,产生“孤儿 Pod”成本。

4.4 Prometheus 采集配置与故障排查

Prometheus 作为统一采集层,其 scrape_config 配置直接决定数据质量。以下是一个针对资源画像优化的采集配置模板:

scrape_configs:
  # 采集 cAdvisor 指标(通过 kubelet 的 /metrics/cadvisor 端点)
  - job_name: 'kubelet-cadvisor'
    kubernetes_sd_configs:
      - role: node
    relabel_configs:
      - source_labels: [__meta_kubernetes_node_name]
        target_label: node
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
    metric_relabel_configs:
      # 保留核心指标,降低基数
      - source_labels: [__name__]
        regex: 'container_(cpu|memory|network|fs)_(usage|working_set|bytes|total)'
        action: keep
      # 统一容器标签
      - source_labels: [container]
        target_label: container_name

  # 采集 kube-state-metrics 指标
  - job_name: 'kube-state-metrics'
    kubernetes_sd_configs:
      - role: pod
        selectors:
          - role: pod
            label: 'app.kubernetes.io/name=kube-state-metrics'
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_node_name]
        target_label: node
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)

4.4.1 采集故障排查清单

故障现象 可能原因 排查命令 / 方法
cAdvisor 指标全部缺失 kubelet 未暴露 /metrics/cadvisor 端点 curl -k https://<node-ip>:10250/metrics/cadvisor
KSM 指标部分缺失 RBAC 权限不足或 KSM 版本过旧 kubectl logs -n kube-system <ksm-pod>
标签关联失败 relabel 规则未正确映射标签 Prometheus Target 页面查看 labels 是否完整
高基数导致 Prometheus OOM 未过滤非必要指标或容器标签过多 检查 tsdb status 中 series 数量

4.5 数据源对比与选型建议

维度 cAdvisor kube-state-metrics Node Exporter
数据粒度 容器级 资源对象级 节点级
核心用途 实际资源消耗 归属与元数据 节点总量与利用率
采集方式 kubelet 内嵌 /metrics/cadvisor 独立 Service 暴露 /metrics DaemonSet 部署 /metrics
基数风险 高(每个容器每个指标一条时间序列) 中(每个资源对象一条时间序列) 低(每个节点一条时间序列)
故障排查优先级 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
最佳实践:在资源画像的初期建设阶段,优先确保 cAdvisor 和 kube-state-metrics 的数据完整性与标签一致性。建议在 Prometheus 中设置告警规则:当 container_cpu_usage_seconds_total 或 kube_pod_info 在 5 分钟内无数据时触发告警,避免成本分摊模型在“数据真空”下运行。

4.6 本章小结

资源画像的数据采集是成本分摊模型的“地基”。cAdvisor 提供容器级资源消耗的“硬数据”,kube-state-metrics 提供资源归属的“软元数据”,Prometheus 则负责将两者在时间维度上对齐。在实际运维中,80% 的成本分摊故障源于数据采集层的标签错乱或指标缺失。掌握本章的指标清单、采集配置和故障排查清单,能够帮助团队快速定位并修复数据链路问题,确保成本分摊模型的准确性与可审计性。