2. 资源画像基础:定义、关键指标与采集原理
资源画像是云原生成本分摊模型的核心数据底座。它通过持续观测工作负载(Pod、Node、命名空间)在 CPU、内存、网络、存储四个维度的实际用量,生成一组高保真、带时间戳的“资源消费快照”。没有准确的资源画像,任何分摊模型都只是“黑盒估算”。
2.1 资源画像的定义与价值
资源画像(Resource Profile)是对云原生环境中每个可计费单元(通常以 Pod 为最小粒度)在特定时间窗口内资源消耗行为的数字化描述。它包含三个核心特征:
- 多维度:同时覆盖 CPU、内存、网络 I/O、存储 I/O 与容量。
- 时间序列化:以秒/分钟级粒度记录,支持聚合与回放。
- 可归因:通过标签(Labels)与注解(Annotations)关联到业务单元、团队或项目。
关键认知:资源画像不是“Request/Limit”的静态配置,而是“实际使用量”的动态记录。成本分摊必须基于画像,而非基于调度承诺。
2.2 关键指标定义与采集粒度
下表列出资源画像的四大类关键指标及其在 Kubernetes 环境中的典型采集来源与粒度:
| 维度 | 核心指标 | 采集来源 | 推荐粒度 | 备注 |
|---|---|---|---|---|
| CPU | cpu/usage_rate (cores) | cAdvisor / Metrics Server | 15s – 60s | 容器级别,取 container_cpu_usage_seconds_total 的速率 |
| cpu/throttled_seconds | cgroup cpu.stat | 60s | 识别 CPU 限流,辅助判断资源争抢 | |
| 内存 | memory/usage_bytes | cAdvisor / Metrics Server | 15s – 60s | container_memory_working_set_bytes 为最准确值 |
| memory/rss_bytes | cgroup memory.stat | 60s | 排除缓存/缓冲区,反映真实应用内存占用 | |
| 网络 | network/rx_bytes_total | cAdvisor / eBPF | 30s – 60s | 容器网络接口入向流量 |
| network/tx_bytes_total | cAdvisor / eBPF | 30s – 60s | 容器网络接口出向流量 | |
| 存储 | storage/fs_usage_bytes | cAdvisor / CSI 插件 | 60s – 300s | 容器层(emptyDir)与持久卷(PVC)容量 |
| storage/fs_iops | CSI 插件 / Node Exporter | 60s | 块存储场景下的读写操作次数 |
实践建议:在成本分摊模型中,CPU 和内存通常占分摊权重的 80% 以上。网络和存储指标在数据密集或 I/O 密集型工作负载中不可忽略,建议按实际流量/容量比例计入分摊因子。
2.3 采集原理:从 cgroup 到 Prometheus
Kubernetes 资源画像的采集链路遵循“内核 cgroup → kubelet/cAdvisor → Metrics Server / Prometheus → 成本引擎”的经典架构。下图展示了核心数据流:
2.4 采集原理的关键技术细节
资源画像的准确性取决于采集层的三个关键技术决策:
- 指标源选择:cAdvisor 暴露的
container_cpu_usage_seconds_total和container_memory_working_set_bytes是业界标准。避免直接使用container_memory_usage_bytes,因为它包含缓存,会导致内存画像偏高 20%~40%。 - 采样与聚合策略:Prometheus 默认 15s 拉取一次。在成本分摊场景中,建议将原始数据按 5 分钟窗口聚合为 P50/P90/P99 分位数,以消除瞬时尖刺对分摊结果的影响。
- 标签传递与保留:必须确保 Pod 的
namespace、pod、container标签以及业务自定义标签(如team、project、env)在采集链路中不被丢弃。这是后续按维度分摊的基础。
常见陷阱:部分集群使用 kube-state-metrics 暴露的
kube_pod_container_resource_requests 作为成本计算依据。这会导致“申请即消费”的误差——实际利用率可能只有 30%~60%。资源画像必须使用实际用量指标,而非调度请求量。
2.5 资源画像数据模型示例
以下是一个标准化的资源画像记录结构(以 JSON 格式表示),用于成本分摊引擎的输入:
{
"timestamp": "2025-03-21T14:30:00Z",
"window": "5m",
"workload": {
"namespace": "production",
"pod": "api-server-7d8f9c6b4-x2y3z",
"container": "api-server",
"labels": {
"team": "platform",
"service": "api-gateway",
"env": "prod"
}
},
"resources": {
"cpu": {
"usage_avg_cores": 0.85,
"usage_p99_cores": 1.20,
"request_cores": 2.0,
"limit_cores": 4.0
},
"memory": {
"usage_avg_bytes": 524288000,
"usage_p99_bytes": 734003200,
"working_set_bytes": 503316480,
"request_bytes": 1073741824,
"limit_bytes": 2147483648
},
"network": {
"rx_bytes_total": 157286400,
"tx_bytes_total": 104857600
},
"storage": {
"ephemeral_usage_bytes": 20971520,
"pvc_usage_bytes": 1073741824
}
}
}
最佳实践:在生成资源画像时,同时保留
request 和 usage 字段。这允许成本分摊模型支持“混合分摊策略”——例如,基础资源按 request 分摊,弹性资源按 usage 分摊,从而兼顾公平性与效率激励。