#如何定义自定义成本模型
本指南展示了如何通过定义自定义成本模型来添加新的计费项。工作流程包括四个部分:
- 准备使用指标
- 准备标签指标
- 为成本管理智能体添加采集配置
- 为成本管理服务器添加展示配置
作为具体示例,我们将添加两个 GPU 计费项:GPU 计算核数(cores)和 GPU 内存,并启用按标签定价。
#目录
#准备使用指标
使用指标表示需要计费的消耗。提供一个 PromQL 查询,用于按步长(例如 5 分钟)聚合使用量。每个步长产生一个数据点,表示前一时间窗口内的使用量;最终使用量是所选时间范围内的总和。
Prometheus 指标类型包括 Counter、Gauge、Summary 和 Histogram。对于使用量,应使用 Counter 或 Gauge。示例:
# Counter 示例(例如 GPU 核心使用时间):
vgpu_core_usage_seconds_total{"containeridx":"0","deviceuuid":"GPU-2eec4202-80dc-870f-3ca5-25879d96eca7","endpoint":"monitor","instance":"10.3.0.130:9395","ip":"192.168.131.32","job":"hami-scheduler","namespace":"kube-system","node_name":"192.168.131.32","nodename":"192.168.133.48","pod":"hami-scheduler-86b7ff47c6-sp7kb","podname":"pytorch-cuda12-1-57d9ff4544-bqkvg","podnamespace":"yulin-2","service":"hami-scheduler","zone":"vGPU"}
# 对应的使用查询(步长 = 5 分钟):
sum by (deviceuuid, podnamespace) (rate(vgpu_core_usage_seconds_total{}[5m]))
# Gauge 示例(例如 GPU 内存使用字节数):
vgpu_memory_usage_bytes{"containeridx":"0","deviceuuid":"GPU-2eec4202-80dc-870f-3ca5-25879d96eca7","endpoint":"monitor","instance":"10.3.0.130:9395","ip":"192.168.131.32","job":"hami-scheduler","namespace":"kube-system","node_name":"192.168.131.32","nodename":"192.168.133.48","pod":"hami-scheduler-86b7ff47c6-sp7kb","podname":"pytorch-cuda12-1-57d9ff4544-bqkvg","podnamespace":"yulin-2","service":"hami-scheduler","zone":"vGPU"}
# 对应的使用查询(步长 = 5 分钟):
sum by (deviceuuid, podnamespace) (avg_over_time(vgpu_memory_usage_bytes{}[5m]))#准备标签指标
标签指标为使用量附加属性,以便可以按标签定价。它们必须能与使用指标进行关联——至少共享一个标签(例如 deviceuuid)——这样系统才能用这些属性丰富使用数据。
标签指标使用 Gauge。示例:
# 标签指标(标签字段在此示例中以 label_ 开头):
vgpu_device_labels{"deviceuuid":"GPU-2eec4202-80dc-870f-3ca5-25879d96eca7","label_device":"nvidia","label_modelName":"Tesla T4","podnamespace":"yulin-1"}
# 标签指标查询:
vgpu_device_labels{}
# 使用查询与标签查询的关系(GPU 核心和内存示例):
# 1) 使用查询按 (deviceuuid, podnamespace) 分组,每个序列包含 deviceuuid
# 2) 标签查询按自身标签分组,每个序列包含 deviceuuid
# 3) 因为两者都包含唯一的 deviceuuid,标签查询中的标签可以附加到使用数据上#添加采集配置(成本管理智能体)
在每个运行成本管理智能体的集群中创建 ConfigMap,用于声明需要采集的内容。
一个典型的采集记录(GPU 核心/内存)映射到配置字段示例如下:
{
"id": "cab9881e380fcf72726ccf45565ffc2d", # 根据约定字段自动生成
"kind": "Vgpu", # 与配置中的 kind 一致
"name": "GPU-2eec4202-80dc-870f-3ca5-25879d96eca7", # 来自 usage.mappers.name
"namespace": "cpaas-system", # 来自 usage.mappers.namespace
"cluster": "default-cluster", # 智能体运行的集群
"project": "cpaas-system", # 从 namespace 推导
"labels": { # 如果配置了 labels.query,则来自标签查询
"key1": "val1",
"key2": "val2"
},
"date": "2024-04-29T00:00:00Z", # 当天起始时间
"period": "hourly", # 与配置中的 period 一致
"start": "2024-04-29T00:05:00Z", # 期间起始时间
"end": "2024-04-29T00:59:59Z", # 期间结束时间
"category": "VgpuCore", # 与配置中的 category 一致
"item": "VgpuCoreUsed", # 与配置中的 item 一致
"usage": 200 # 来自使用查询结果
}现在为智能体创建 ConfigMap(GPU 核心和内存):
apiVersion: v1
data:
config: |
- kind: Vgpu # 必填;必须与服务器配置一致
category: VgpuCore # 必填;必须与服务器配置一致
item: VgpuCoreUsed # 必填且唯一;必须匹配服务器配置
period: Hourly # 必填;Hourly 或 Daily,推荐 Hourly
labels: # 可选;通过此查询为使用量添加标签
query: "vgpu_core_labels{}" # 例如,添加 GPU 型号、厂商标签
mappers:
name: deviceuuid # 将 deviceuuid 映射为 name
namespace: podnamespace # 将 podnamespace 映射为 namespace
cluster: "" # 为空时自动填充当前集群
project: "" # 为空时自动从 namespace 填充项目
usage: # 必填;使用查询(按 deviceuuid,podnamespace 分组)
query: "sum by (deviceuuid, podnamespace) (rate(vgpu_core_usage_seconds_total{}[5m]))"
step: 5m # 必填;采样步长
mappers:
name: deviceuuid # 将 deviceuuid 映射为 name
namespace: podnamespace # 将 podnamespace 映射为 namespace
cluster: "" # 为空时自动填充
project: "" # 为空时自动填充
- kind: Vgpu # 第二个计费项
category: VgpuMemory # 必须与服务器配置一致
item: VgpuMemoryUsed # 唯一的 item 名称
period: Hourly
labels:
query: "vgpu_core_labels{}"
mappers:
name: deviceuuid
namespace: podnamespace
cluster: ""
project: ""
usage:
query: "sum by (deviceuuid, podnamespace) (avg_over_time(vgpu_memory_usage_bytes{}[5m]))"
step: 5m
mappers:
name: deviceuuid
namespace: podnamespace
cluster: ""
project: ""
kind: ConfigMap
metadata:
labels:
cpaas.io/slark.collection.config: "true" # 必填;启用采集配置
name: slark-agent-project-config-vgpu
namespace: cpaas-system # 必填;添加 yaml 后,需要重启智能体 Pod 以重新加载配置。
kubectl delete pods -n cpaas-system -l service_name=slark-agent#添加展示/存储配置(成本管理服务器)
在运行成本管理服务器的集群中创建 ConfigMap,用于声明计费项、计费方法、单位和展示名称。此配置告诉服务器计费内容及方式。
apiVersion: v1
data:
config: |
- name: VgpuCore # 计费项名称;必须与上述 category 匹配
displayname:
zh: "Vgpu"
en: "Vgpu"
methods: # 计费方法列表(唯一名称)
- name: Usage # 方法名称
displayname:
zh: "使用量"
en: "Used Usage"
item: VgpuCoreUsed # 必须匹配智能体配置中的 item
divisor: 1000 # 单位换算(例如 mCPU 转核数)
unit:
zh: "core-hours"
en: "core-hours"
- name: VgpuMemory # 第二个计费项
displayname:
zh: "Vgpu 显存"
en: "VgpuMemory"
methods:
- name: Used
displayname:
zh: "使用量"
en: "Used Usage"
item: VgpuMemoryUsed
divisor: 1073741824 # 字节 -> Gi
unit:
zh: "Gi-hours"
en: "Gi-hours"
kind: ConfigMap
metadata:
labels:
cpaas.io/slark.display.config: "true" # 必填;启用展示/存储配置
name: slark-display-config-for-vgpu
namespace: kube-public # 必填;添加 yaml 后,需要重启服务器 Pod 以重新加载配置。
kubectl delete pods -n cpaas-system -l service_name=slark-server#注意事项与最佳实践
- 保持智能体和服务器配置中的命名一致:
kind、category和item必须匹配。 - 推荐使用 Hourly 以获得更细粒度和更快反馈。
- 确保标签指标能通过共享标签(例如
deviceuuid)与使用指标关联。 - 在上线前本地验证 PromQL 查询;监控初始运行的数据合理性。
- 从少量集群和计费项开始,验证后再逐步扩展。