4. 成本数据采集与计量:Prometheus与Kube-state-metrics的指标采集、成本数据的ETL处理、存储方案

成本分摊与资源画像的协同优化,其底层基础是准确、完整、可追溯的原始成本数据。本章聚焦于如何从Kubernetes集群中采集资源用量指标,通过ETL管道清洗与关联,并选择适合长期存储与高可用查询的时序数据库方案。

4.1 指标采集层:Prometheus与Kube-state-metrics

Kubernetes集群内的资源消耗数据主要来自两个维度:实时运行指标(CPU/内存/网络)和资源状态元数据(Pod/Node/Namespace标签、请求量、限制量)。Prometheus负责前者,Kube-state-metrics(KSM)负责后者。

组件 数据来源 核心指标示例 采集频率
Prometheus cAdvisor(kubelet内置)、Node Exporter container_cpu_usage_seconds_total
container_memory_working_set_bytes
15s ~ 30s
Kube-state-metrics Kubernetes API Server kube_pod_container_resource_requests
kube_pod_labels
60s ~ 120s
关键原则:成本计量必须同时依赖实际用量(Prometheus)和资源规格(KSM)。仅用量无法区分共享资源的分摊比例,仅规格无法反映真实消耗。

4.2 成本数据的ETL处理

原始指标无法直接用于成本分摊,必须经过提取(Extract)、转换(Transform)、加载(Load)三个步骤,形成标准化的成本事实表。

4.2.1 提取阶段

  • Prometheus查询:通过PromQL聚合指定时间窗口(如1小时)内的CPU/内存平均使用量。
  • KSM标签注入:从kube_pod_labels中提取namespace、app、team、cost_center等业务标签。
  • 节点单价映射:从外部配置(如云厂商价目表或内部定价表)获取每核每小时、每GiB每小时的成本单价。

4.2.2 转换阶段

核心转换逻辑包括:

  1. 用量归一化:将原始计数器(如container_cpu_usage_seconds_total)转换为平均使用量(核·时)。
  2. 标签对齐:将Pod用量与KSM中的kube_pod_labels通过namespace + pod + container进行关联。
  3. 成本计算:成本 = 用量 × 单价 × 分摊系数(分摊系数用于处理共享资源如节点预留、DaemonSet开销)。
  4. 数据清洗:过滤掉PENDING或Evicted状态的Pod,处理缺失标签的“孤儿”资源。
ETL示例(伪代码):
-- 1. 提取CPU用量(核·时)
SELECT
    pod_namespace,
    pod_name,
    container_name,
    AVG(cpu_usage_core_seconds) / 3600 AS cpu_core_hours
FROM prometheus.container_cpu_usage
WHERE time >= '2025-01-01 00:00:00' AND time < '2025-01-01 01:00:00'
GROUP BY pod_namespace, pod_name, container_name;

-- 2. 关联KSM标签
SELECT
    cpu.pod_namespace,
    cpu.pod_name,
    cpu.cpu_core_hours,
    ksm.labels['team'] AS team,
    ksm.labels['cost_center'] AS cost_center
FROM cpu_usage cpu
JOIN kube_state_metrics.pod_labels ksm
    ON cpu.pod_namespace = ksm.namespace
    AND cpu.pod_name = ksm.pod;

-- 3. 计算成本
SELECT
    team,
    cost_center,
    SUM(cpu_core_hours * 0.042) AS cpu_cost_usd  -- 假设单价$0.042/核·时
FROM enriched_data
GROUP BY team, cost_center;

4.2.3 加载阶段

转换后的成本数据写入成本事实表,通常存储在OLAP数据库(如ClickHouse)或列式存储中,用于后续的多维分摊查询与资源画像分析。

4.3 存储方案:Thanos vs. VictoriaMetrics

Prometheus单实例无法满足长期存储(>30天)和高可用查询的需求。Thanos和VictoriaMetrics是当前云原生成本数据存储的两大主流方案。

选型提示:如果团队已有Prometheus Operator且希望保留完整PromQL兼容性,优先选择Thanos;如果追求极致性能与低资源消耗,且对PromQL兼容性要求不苛刻,VictoriaMetrics更具优势。
特性 Thanos VictoriaMetrics
架构复杂度 多组件(Sidecar/Store/Compactor/Query/Ruler) 单二进制(单节点)或双组件(vminsert/vmselect/vmstorage)
PromQL兼容性 完全兼容(原生PromQL引擎) 高度兼容(自研引擎,部分边缘函数有差异)
长期存储 对象存储(S3/GCS/MinIO) 本地磁盘 + 对象存储(通过vmbackup/vmrestore)
压缩率 中等(依赖Prometheus TSDB) 高(自研列式压缩,通常比Thanos节省50%+空间)
查询性能 中等(需合并多个Store Gateway结果) 高(并行扫描+预聚合)
运维成本 高(组件多,需配置Sidecar/Store/Compactor) 低(单节点即可运行,集群模式也较简单)
适用场景 大规模多集群、需要全局视图、已有Prometheus生态 高性能查询、资源受限环境、快速部署

4.4 成本数据采集与存储架构

下图展示了从指标采集到成本数据存储的完整链路:

成本数据采集与存储架构 Kubernetes 集群 Pod / Node / Namespace cAdvisor / Node Exporter CPU / 内存 / 网络用量 Kube-state-metrics 资源请求 / 标签 / 状态 Prometheus 采集 + ETL 管道 PromQL 聚合 → 标签关联 → 用量归一化 → 成本计算 过滤孤儿资源 / 处理缺失标签 / 分摊系数注入 Thanos 存储方案 Sidecar → Store Gateway → Compactor 对象存储(S3 / GCS / MinIO) 全局查询视图 / 多集群聚合 VictoriaMetrics 存储方案 vminsert → vmstorage → vmselect 本地磁盘 + 对象存储备份 高压缩率 / 低资源消耗 成本分摊引擎 & 资源画像分析 多维查询(团队/应用/环境)→ 分摊计算 → 画像生成

4.5 实践建议与避坑指南

  • 标签一致性:确保KSM中kube_pod_labels的标签键与成本分摊模型中的维度一致,避免因大小写或下划线差异导致关联失败。
  • 时间窗口对齐:Prometheus采集频率(15s)与KSM采集频率(60s)不同,ETL中需使用avg_over_time或rate函数将数据对齐到相同粒度(如1小时)。
  • 存储容量规划:成本数据通常需要保留12个月以上。Thanos的对象存储成本较低但查询延迟较高;VictoriaMetrics本地磁盘性能好但需规划备份策略。
  • 孤儿资源处理:未被任何Pod使用的节点资源(如DaemonSet、系统组件)应通过分摊系数均匀分配到所有租户,避免成本黑洞。
关键指标监控:
  • prometheus_tsdb_head_series:监控Prometheus序列数,避免超过内存限制。
  • thanos_store_bucket_operations_total:监控Thanos对象存储请求成功率。
  • vm_vminsert_rows_inserted_total:监控VictoriaMetrics写入吞吐量。