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_totalcontainer_memory_working_set_bytes |
15s ~ 30s |
| Kube-state-metrics | Kubernetes API Server | kube_pod_container_resource_requestskube_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 转换阶段
核心转换逻辑包括:
- 用量归一化:将原始计数器(如
container_cpu_usage_seconds_total)转换为平均使用量(核·时)。 - 标签对齐:将Pod用量与KSM中的
kube_pod_labels通过namespace+pod+container进行关联。 - 成本计算:
成本 = 用量 × 单价 × 分摊系数(分摊系数用于处理共享资源如节点预留、DaemonSet开销)。 - 数据清洗:过滤掉
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 成本数据采集与存储架构
下图展示了从指标采集到成本数据存储的完整链路:
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写入吞吐量。