3. 成本数据采集架构设计:使用 kube-state-metrics、node_exporter、cAdvisor 采集资源指标
在云原生 FinOps 实践中,成本数据的质量直接决定调优与审计的准确性。本章聚焦于构建一套轻量、标准、可审计的指标采集层,核心组件为 kube-state-metrics (KSM)、node_exporter 与 cAdvisor。三者分别从集群状态、节点资源、容器运行时三个维度提供原始数据,是后续成本分摊与漂移检测的基础。
3.1 三大采集组件的职责边界
为避免数据冗余与口径冲突,必须明确每个组件的采集范围与输出指标类型。下表从数据来源、核心指标、采集周期与 Prometheus 集成方式四个维度进行对比:
| 组件 | 数据来源 | 核心指标示例 | 采集周期 | Prometheus 集成 |
|---|---|---|---|---|
| kube-state-metrics | Kubernetes API Server (资源对象状态) | kube_pod_resource_requests, kube_deployment_spec_replicas, kube_namespace_labels |
默认 30s(可配置) | 直接暴露 /metrics 端点 |
| node_exporter | 宿主机 /proc, /sys, 硬件监控接口 | node_cpu_seconds_total, node_memory_MemTotal_bytes, node_network_receive_bytes_total |
默认 15s(可配置) | DaemonSet 部署,每个节点暴露 /metrics |
| cAdvisor | 容器运行时 (cgroups, Docker/containerd) | container_cpu_usage_seconds_total, container_memory_working_set_bytes, container_network_receive_bytes_total |
默认 10s(内嵌于 kubelet) | 通过 kubelet /metrics/cadvisor 端点暴露 |
kube_pod_resource_requests 用于预留成本(承诺使用量),container_cpu_usage_seconds_total 用于实际消耗成本(按量计费)。两者结合可计算资源利用率与浪费比例。
3.2 采集架构总览
下图展示了三个组件在 Kubernetes 集群中的部署位置与数据流向。Prometheus Server 通过 Service 发现机制分别拉取 KSM、node_exporter 与 kubelet/cAdvisor 的指标,最终统一存储于 TSDB 中供成本引擎查询。
3.3 组件部署与关键配置
3.3.1 kube-state-metrics (KSM)
KSM 监听 API Server 的资源对象变更,生成以 kube_* 为前缀的指标。推荐使用 Helm Chart 部署,并开启 --metric-labels-allowlist 以保留成本分摊所需的标签。
# Helm 安装示例
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm upgrade --install kube-state-metrics prometheus-community/kube-state-metrics \
--namespace monitoring \
--set collectors.namespaces=true \
--set collectors.pods=true \
--set collectors.deployments=true \
--set metricLabelsAllowlist="pods=[*],namespaces=[team,env,cost-center]"
metricLabelsAllowlist,KSM 默认不暴露 Pod/Namespace 的自定义标签,导致成本引擎无法按业务维度(如团队、环境)进行分摊。务必在部署时显式声明所需标签白名单。
3.3.2 node_exporter
node_exporter 以 DaemonSet 方式运行于每个节点,采集 CPU、内存、磁盘、网络等宿主机级指标。在成本模型中,node_cpu_seconds_total 与 node_memory_MemTotal_bytes 用于计算节点总容量,进而推导节点利用率。
# DaemonSet 关键配置片段
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true
containers:
- name: node-exporter
image: prom/node-exporter:v1.7.0
args:
- --path.procfs=/host/proc
- --path.sysfs=/host/sys
- --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
ports:
- containerPort: 9100
3.3.3 cAdvisor (通过 kubelet 暴露)
cAdvisor 已内嵌于 kubelet 中,无需单独部署。Prometheus 通过 kubelet /metrics/cadvisor 端点拉取容器级指标。关键指标包括:
container_cpu_usage_seconds_total— 容器 CPU 累计使用时间(实际消耗)container_memory_working_set_bytes— 容器内存工作集(实际消耗)container_network_receive_bytes_total— 容器网络接收字节(网络成本)
# Prometheus 采集配置 (scrape_configs 片段)
- job_name: 'kubelet-cadvisor'
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer__file: /var/run/secrets/kubernetes.io/serviceaccount/
relabel_configs:
- target_label: __metrics_path__
replacement: /metrics/cadvisor
3.4 指标关联与成本计算基础
三个组件的指标必须通过 Pod 名称、命名空间、节点名称 等标签进行关联,才能计算出单个 Pod 或工作负载的实际成本。以下是一个典型的 PromQL 查询示例,用于计算某个命名空间下所有 Pod 的 CPU 实际使用量(核·秒):
# 计算命名空间 "production" 下所有 Pod 的 CPU 实际使用量(核·秒)
sum by (namespace, pod) (
rate(container_cpu_usage_seconds_total{namespace="production"}[5m])
) * on (pod, namespace) group_left(owner_name, owner_kind)
kube_pod_owner_info{namespace="production"}
Pod 实际成本 = (CPU 使用量 / 节点总容量) × 节点单价 + (内存使用量 / 节点总容量) × 节点单价其中 CPU/内存使用量来自 cAdvisor,节点总容量来自 node_exporter,Pod 归属信息来自 KSM。
3.5 采集链路健康检查与数据质量保障
为确保成本数据的可靠性,必须对采集链路实施持续监控。下表列出了三个组件的关键健康指标与告警阈值:
| 组件 | 健康指标 | 告警阈值 | 影响 |
|---|---|---|---|
| kube-state-metrics | up{job="kube-state-metrics"} |
== 0 持续 1m | 资源请求/标签数据缺失,成本分摊失效 |
| node_exporter | up{job="node-exporter"} |
< 节点总数 80% 持续 2m | 节点容量数据不完整,成本计算偏差 |
| cAdvisor (kubelet) | scrape_samples_scraped{job="kubelet-cadvisor"} |
下降 > 20% 持续 5m | 容器实际用量缺失,无法计算真实成本 |
record 规则,将三个组件的核心指标预先关联并存储为 :cost_cpu_usage:rate5m 等聚合指标,降低成本查询时的计算压力,同时便于配置漂移审计时进行历史数据比对。