Kubernetes 多团队资源计量与成本分摊实战

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。
本文缩写(英文全称与中文含义)
缩写 英文全称/名称 中文含义
API Application Programming Interface 应用程序编程接口
CPU Central Processing Unit 中央处理器
CR Custom Resource Kubernetes 自定义资源对象
CRD Custom Resource Definition Kubernetes 自定义资源定义
CSV Comma-Separated Values 逗号分隔值格式
FinOps FinOps 结合工程、财务与业务进行云成本管理的实践名称
GiB Gibibyte 二进制容量单位,1 GiB = 2³⁰ 字节
GPU Graphics Processing Unit 图形处理器
HA High Availability 高可用
HTTP Hypertext Transfer Protocol 超文本传输协议
ID Identifier 标识符
IOPS Input/Output Operations Per Second 每秒输入输出操作数
JSON JavaScript Object Notation 一种结构化数据格式
LB Load Balancer 负载均衡器
NAT Network Address Translation 网络地址转换
PV Persistent Volume 持久卷
PVC Persistent Volume Claim 持久卷申领
RBAC Role-Based Access Control 基于角色的访问控制
RDS Relational Database Service AWS 关系型数据库服务
S3 Simple Storage Service AWS 对象存储服务
SKU Stock Keeping Unit 库存单位;云计费中指具体计费项
UI User Interface 用户界面
UTC Coordinated Universal Time 协调世界时

目标与落地边界#

多个团队共用一个 Kubernetes 集群时,需要回答三个问题:资源属于谁、占用了多少、应承担多少钱。推荐先做 Showback(展示费用),经过完整账期验证后再做 Chargeback(内部结算)。

本文提供一个单集群试点方案:Namespace 归属 + Prometheus 指标 + OpenCost 成本分配 + 月度对账。命令示例用于测试集群;已有监控系统的集群应复用现有组件。本文提供配置和验收步骤,不代表已在你的集群部署验证。

数据 作用 不能替代什么
Requests / Limits / Quota 申请量、运行上限、团队额度 不等于实际使用量或云账单
CPU、内存历史指标 核时、GiB 时、利用率 不直接给出折扣后的真实费用
OpenCost Allocation 将成本模型分配到工作负载 不能默认视为财务最终账单
云成本与用量报告 实际价格、折扣、账单调整 通常不能单独解释每个 Pod 的份额

1. 先固定计费规则#

试点建议采用以下规则,写入平台与团队共同认可的成本说明:

  • 归属:一个 Namespace 只属于一个团队,一个团队可以有多个 Namespace。
  • 展示:同时展示 Requests、实际 Usage、OpenCost 分配成本和最终结算成本。
  • 计算:以节点/资源池和时间窗口分配 CPU、内存成本,不把不同价格的节点混成一个固定单价。
  • 公共组件:平台维护明确清单;先单列,再按团队直接成本比例分摊。
  • 闲置容量:试点阶段由平台单列承担,专属节点池的闲置可按约定归对应团队。
  • 无归属资源:进入 unallocated 桶,不能丢弃,也不能默认为零费用。
  • 账期:本例按 UTC 自然日出日报,月账单采用明确的起止时间;展示人民币时另记录汇率和日期。
  • 数据缺口:标记为不完整,补数或人工确认后才能结算。

公共成本可以固定比例分摊、按代理指标分摊,或由平台统一承担;没有唯一通用公式,关键是规则可解释且保持一致。参考 FinOps 成本分配指南。

2. 团队资源归属与额度#

2.1 Namespace 与标签#

shared-prod
├── payment-prod      team=payment
├── payment-dev       team=payment
├── order-prod        team=order
├── monitoring        平台公共成本
├── opencost          平台公共成本
└── kube-system       平台公共成本

保存为 payment-namespace.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: payment-prod
  labels:
    team: payment
    cost-center: payment
    environment: prod
kubectl apply -f payment-namespace.yaml
kubectl get namespaces -L team,cost-center,environment

平台维护 Namespace → team → cost-center 的权威映射;部署模板也添加 team、app 和 environment 标签。Namespace 标签不会自动继承到 Pod,不能假设给 Namespace 打标签后,所有按 Pod label 聚合的工具就自动识别团队。

本方案先按 Namespace 导出费用,再按权威映射聚合团队。映射需保存生效起止时间,Namespace 转交团队时不能用今天的归属重写历史账单。

通过 RBAC 限制团队只能操作自己的 Namespace,由平台维护归属标签、Quota 和 LimitRange。可用 Kyverno 校验标签和资源声明,进一步验证 Pod 的团队标签与 Namespace 一致;不能只校验“标签非空”。Namespace 本身也不构成完整安全隔离,仍需 NetworkPolicy 等措施。参考 Kubernetes 多租户。

2.2 Quota 与 LimitRange#

保存为 payment-budget.yaml:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-budget
  namespace: payment-prod
spec:
  hard:
    requests.cpu: "8"
    requests.memory: 16Gi
    limits.cpu: "16"
    limits.memory: 32Gi
    requests.storage: 100Gi
    persistentvolumeclaims: "10"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: container-defaults
  namespace: payment-prod
spec:
  limits:
    - type: Container
      defaultRequest:
        cpu: 100m
        memory: 128Mi
      default:
        cpu: "1"
        memory: 512Mi
kubectl apply -f payment-budget.yaml
kubectl -n payment-prod describe resourcequota team-budget

这些数值是演示额度,应按业务调整。Quota 中的 8 核是团队申请量上限,不代表已经为团队预留 8 核,也不应直接收取 8 × 整月小时数 的费用。参考 ResourceQuota。

3. “2 核 × 10 小时”中的时间怎么算#

3.1 Requests:申请量在时间上的累计#

假设一个普通单容器 Pod 从 08:00 到 18:00 都在运行,CPU request 一直为 2 核:

申请累计量 = 2 核 × 10 小时 = 20 核时

单位是“核时”,不是“核”。监控系统周期性采样 requests,然后按时间积分,不是事后只看当前 Pod 的年龄。若中间扩容:

时段 Pod 数量 每个 Pod 的 CPU request 小计
08:00–12:00 1 2 核 8 核时
12:00–18:00 3 2 核 36 核时
总计 44 核时

通用公式:申请核时 = Σ(每段申请核数 × 该段秒数 / 3600)。

必须明确 Pod 状态口径:未绑定节点的 Pending Pod 不消耗节点分配容量;已经绑定节点但拉取镜像失败、初始化或终止中的 Pod,需要按工具的实际模型单独验证。不能把“创建到删除”的墙钟时间直接当成 OpenCost 的计费时间。OpenCost 对 Pod 状态的覆盖存在明确边界,详见 OpenCost 规范。

3.2 Usage:CPU 真正执行的累计时间#

container_cpu_usage_seconds_total 是累计 CPU 秒数。假设同一组容器这 10 小时内累计消耗 18,000 CPU 秒:

实际消耗 = 18,000 / 3,600 = 5 核时
平均使用 = 5 核时 / 10 小时 = 0.5 核
相对申请量的平均利用率 = 5 / 20 = 25%

CPU 秒跨核心累计:同时占满 2 核运行 1 秒,约产生 2 CPU 秒。Pod 存活 10 小时,不等于满负荷运行了 10 小时。

量 本例结果
运行持续时间 10 小时
Requests 累计量 20 核时
实际 CPU 消耗 5 核时
相对 Requests 利用率 25%

容器重启后计数器可能重置,应该对每条原始计数器使用 increase / rate,再做聚合。不要用最后值减最早值,也不要先加总不同容器的计数器再计算增长率。参考 Prometheus 查询函数。

3.3 内存、存储与网络#

  • 内存用量通常选 working set,按 GiB 对时间积分,得到 GiB 时;它不是 CPU 那样的累计计数器,不能套用 increase。
  • 内存 request 同样积分成 GiB 时;working set 也不等于业务堆内存。
  • PVC 通常按供应容量计费,不能只统计文件系统已用字节;额外 IOPS、吞吐、快照应按账单纳入。
  • 网络费用依赖流量方向、可用区、地域、NAT 和负载均衡服务,不能把容器收发总字节统一乘公网出流量价格。

4. 部署 Prometheus 与 OpenCost#

4.1 前置条件与版本#

需要 Helm、kubectl、一个可安装 CRD/RBAC 的测试集群;日报导出还需要 curl、jq。先核对当前上下文:

kubectl config current-context
kubectl get nodes
helm version
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add opencost-charts https://opencost.github.io/opencost-helm-chart
helm repo update
helm search repo prometheus-community/kube-prometheus-stack --versions
helm search repo opencost-charts/opencost --versions

# 替换成经过兼容性核对的 Chart 版本,保存到部署记录。
export MONITORING_CHART_VERSION='<监控 Chart 版本>'
export OPENCOST_CHART_VERSION='<OpenCost Chart 版本>'
helm show values prometheus-community/kube-prometheus-stack --version "$MONITORING_CHART_VERSION" > monitoring-default-values.yaml
helm show values opencost-charts/opencost --version "$OPENCOST_CHART_VERSION" > opencost-default-values.yaml

以下监控安装针对空白测试环境。已有 kube-prometheus-stack 的集群,应把所需选项合并进现有完整 values,再走原有发布流程,避免创建第二套重复抓取的系统。

4.2 监控配置#

保存为 monitoring-values.yaml:

kube-state-metrics:
  metricLabelsAllowlist:
    - namespaces=[team,cost-center,environment]
    - pods=[team,app,environment]
prometheus:
  prometheusSpec:
    scrapeInterval: 30s
    evaluationInterval: 1m
    retention: 45d
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack -n monitoring --create-namespace --version "$MONITORING_CHART_VERSION" -f monitoring-values.yaml --wait --timeout 10m
kubectl -n monitoring get prometheus,pods,services

测试配置没有设置持久化,不能承担生产账单留存。生产需在完整 values 中配置 prometheus.prometheusSpec.storageSpec 的 PVC、StorageClass、容量和备份,或接入经过验证的长期存储;保留期应覆盖完整账期及重算窗口,并监控磁盘使用量。安装前的数据不会自动补齐。

kube-prometheus-stack 通常部署 kube-state-metrics,并配置 kubelet/cAdvisor 抓取。实际能否采到指标必须通过 Targets 验证,不能以 Helm 安装成功代替数据验收。配置依据:官方 Chart values。

4.3 OpenCost 配置#

保存为 opencost-values.yaml。先用上一步 kubectl get services 确认 Prometheus Service 名称,按实际修改:

opencost:
  exporter:
    defaultClusterId: shared-prod
  prometheus:
    internal:
      enabled: true
      serviceName: monitoring-kube-prometheus-prometheus
      namespaceName: monitoring
      port: 9090
    external:
      enabled: false
  metrics:
    serviceMonitor:
      enabled: true
      additionalLabels:
        release: monitoring
      scrapeInterval: 30s
  ui:
    enabled: true
helm upgrade --install opencost opencost-charts/opencost -n opencost --create-namespace --version "$OPENCOST_CHART_VERSION" -f opencost-values.yaml --wait --timeout 5m
kubectl -n opencost get deployment,pods,servicemonitor
kubectl -n opencost logs deployment/opencost --all-containers=true --tail=100
kubectl -n opencost port-forward deployment/opencost 9003:9003 9090:9090

保持转发终端运行,浏览器打开 http://localhost:9090。API 地址为 http://localhost:9003。生产对团队开放 UI/API 前应补充认证授权,避免暴露其他团队的成本数据。

release: monitoring 用于匹配本例 Prometheus 的 ServiceMonitor 选择器,不是 OpenCost 固定要求。已有安装应检查 Prometheus CR 的 serviceMonitorSelector 和 serviceMonitorNamespaceSelector,确保能发现 opencost 命名空间中的对象。参考 OpenCost Helm 安装 和 Chart values。

4.4 数据与价格验收#

在 Prometheus 页面检查 Targets,并执行以下 PromQL,确认有数据、时间新鲜且没有重复抓取:

count(container_cpu_usage_seconds_total{container!="",container!="POD",namespace!=""})
count(container_memory_working_set_bytes{container!="",container!="POD",namespace!=""})
count(kube_pod_container_resource_requests)
count(kube_namespace_labels{label_team!=""})
count(node_cpu_hourly_cost)
count(node_ram_hourly_cost)

多行应分别执行。数量为零或无结果时,先修复采集。还应抽查 node 单价和节点 SKU/地域/Spot 类型;“有价格”不代表“价格正确”。检查 OpenCost 导出指标与已有 kube-state-metrics 是否重叠,对重复指标按 job 过滤或在采集层去重。参考 OpenCost 与 Prometheus 集成。

本例未配置云账单凭据,因此不能宣称完成了折扣、承诺用量或实际账单对接。云环境需按官方提供商指南配置成本报告及最小只读权限;自建集群需配置自定义价格,将采购摊销等成本换成一致的时间单价。参考 OpenCost 安装与提供商配置入口。

5. 用 PromQL 验证资源计量#

以下查询用于单集群核对与趋势分析。前提是每个原始容器仅抓取一次;多集群系统需增加 cluster 过滤和聚合维度,HA 副本需在查询层去重。job/metrics_path 标签因安装方式不同,应先在 Prometheus 中核对。

5.1 过去 24 小时的实际 CPU 核时#

sum by (namespace) (
  increase(container_cpu_usage_seconds_total{
    namespace!="", container!="", container!="POD",
    metrics_path="/metrics/cadvisor"
  }[24h])
) / 3600

在确定的日终时间执行 Instant Query,而非取当前瞬间 CPU 使用率乘 24。范围向量可包含窗口内已删除容器的历史样本;不要再与“当前仍存在的 Pod 清单”关联,否则会漏掉已结束的任务。

increase 会处理可见的计数器重置,并对区间边界做外推,因此结果可能是小数。它不能恢复首次抓取之前、最后一次抓取之后或完全没抓到的使用量;只留下一个样本的短容器无法可靠计算增量。该查询是监控计量,不是毫秒级财务计量器。

5.2 Requests 与内存的 1 分钟记录规则#

保存为 cost-recording-rules.yaml。本例只统计 Running、已绑定节点的普通容器 request;不覆盖 init container 最大值、Pod overhead 或 Pod 级资源声明等完整调度语义,不能替代 OpenCost 分配引擎。

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: namespace-cost-metering
  namespace: monitoring
  labels:
    release: monitoring
spec:
  groups:
    - name: namespace-cost-metering
      interval: 1m
      rules:
        - record: namespace:cpu_requests_running:cores
          expr: |
            sum by (namespace) (
              max by (namespace, pod, uid, container) (
                kube_pod_container_resource_requests{resource="cpu",unit="core",node!=""}
              )
              and on (namespace, pod, uid)
              (max by (namespace, pod, uid) (kube_pod_status_phase{phase="Running"}) == 1)
            )
        - record: namespace:memory_working_set:gib
          expr: |
            sum by (namespace) (
              container_memory_working_set_bytes{
                namespace!="",container!="",container!="POD",
                metrics_path="/metrics/cadvisor"
              }
            ) / 1073741824
kubectl apply -f cost-recording-rules.yaml
kubectl -n monitoring get prometheusrule namespace-cost-metering

还需在 Prometheus 的 Rules 页面确认规则已加载、健康且按分钟产出;只有 CR 创建成功并不代表被选择器选中。本例依赖 kube-state-metrics 的 uid 等标签,升级后应核对实际指标模式。

在记录规则已经覆盖完整一天后,分别查询:

sum_over_time(namespace:cpu_requests_running:cores[24h]) / 60
sum_over_time(namespace:memory_working_set:gib[24h]) / 60

结果分别是申请核时和实际内存 GiB 时。除以 60 的原因:每个样本代表约 1 分钟,即 1/60 小时;如果把规则间隔改成 30 秒,就应除以 120。

这是一分钟矩形积分近似,会受到抓取间隔、陈旧样本、规则停顿、Pod 状态切换影响。Pod 不运行时序列可能不存在,不能仅凭该 Namespace 样本数不足 1440 就判定采集故障;应结合 Prometheus/目标健康、抓取缺口和规则执行失败判断。不能用 avg_over_time × 24 无条件替代积分,否则仅运行 1 小时的 Pod 可能被扩大成 24 小时。

生产对短于采样间隔的 Job,如有严格计费要求,应补充工作负载生命周期记录或更细粒度计量,并明确最低计费粒度。普通分钟采样无法保证完整捕获这类任务。

6. 导出 OpenCost 日报#

OpenCost 的 cpuCoreHours 是其分配模型中的资源量,不能直接当成上一节 CPU counter 算出的实际核时。OpenCost 的资源分配原则包含 request 与 usage 的比较,具体数值受窗口、分辨率、状态和实现版本影响;不能用“整月 request 总量与 usage 总量取最大值”自行替代。参考 Allocation API。

先做滚动窗口检查:

curl --fail --silent --show-error --get http://localhost:9003/allocation --data-urlencode 'window=24h' --data-urlencode 'aggregate=namespace' --data-urlencode 'resolution=1m' --data-urlencode 'includeIdle=true' --data-urlencode 'shareIdle=false' --data-urlencode 'idleByNode=true' > allocation-preview.json
jq -e '.code == 200 and (.data | type == "array")' allocation-preview.json

正式日报必须使用固定窗口;把下面日期替换成已完整采集的 UTC 日期。香港时间一天的 00:00 边界对应前一天 16:00Z,若按本地自然日结算,应转换边界并全程保持一致。

export COST_WINDOW_START='2026-09-20T00:00:00Z'
export COST_WINDOW_END='2026-09-21T00:00:00Z'

curl --fail --silent --show-error --get http://localhost:9003/allocation --data-urlencode "window=${COST_WINDOW_START},${COST_WINDOW_END}" --data-urlencode 'step=24h' --data-urlencode 'resolution=1m' --data-urlencode 'aggregate=namespace' --data-urlencode 'includeIdle=true' --data-urlencode 'shareIdle=false' --data-urlencode 'idleByNode=true' > allocation-day.json

jq -e '.code == 200 and (.data | type == "array") and (.data | length > 0)' allocation-day.json
jq -r '
  ["allocation","cpuCost","ramCost","pvCost","networkCost","totalCost"],
  (.data[] | to_entries[] |
    [.key,.value.cpuCost,.value.ramCost,.value.pvCost,
     .value.networkCost,.value.totalCost]) | @csv
' allocation-day.json > allocation-day.csv

保留原始 JSON;CSV 是便于核对的摘要,totalCost 可能还含 GPU、负载均衡、共享费用或调整项,不能只将展示的四列相加。缺失字段输出为空,需要调查,不能静默补成零。HTTP/JSON 成功及非空也不能证明窗口完整,仍需采集覆盖率检查。

把 __idle__ 等工具特殊项归到单独账目,普通 Namespace 按历史归属表聚合,公共 Namespace 按清单归平台费用。没有映射的 Namespace 必须进入未归属报表。参数示例依据 OpenCost API 示例。

日常可以用调度任务调用集群内 API 导出,不依赖人工 port-forward;导出任务保留日期、cluster ID、Chart/App 版本、价格口径、归属表版本、查询参数和数据质量状态,写入有版本控制/备份的存储。按 cluster + 日期 + 规则版本幂等覆盖或保存修订版,不重复追加费用。

7. 从模型成本到真实账单#

7.1 节点成本不能重复计算#

云厂商通常对一台节点整体收费。CPU 单价和内存单价是对同一节点成本的拆分,不能各自承担 100% 节点费用。需要满足同一窗口内的核算约束:

节点成本 ≈ CPU 分配成本 + 内存分配成本 + GPU 等适用成本
节点成本分配结果 = 团队份额 + 公共工作负载份额 + 闲置/系统开销 + 差异

云账单对账应按节点 ID/资源池、实例类型、地域、购买方式及时间窗口匹配。Spot 与按需价格、承诺用量折扣及预付摊销必须按同一财务口径处理,不能让某个团队承担另一种节点池的价格。

如果目前只有模型价格,可先用其作为分配权重:在同一可比费用池内,某项结算额 = 该项模型份额 / 全部模型份额 × 该费用池实际金额。分母必须包含公共和闲置项;分母为零或数据不完整时应进入差异处理,不能强行分完。该方法是内部约定的归一化方案,不是 OpenCost API 自动保证的行为。

7.2 明确费用范围与避免重复#

费用 归属方法 常见错误
节点计算 OpenCost 分配模型结合节点实际账单 把完整节点账单与分配结果再次相加
PVC/云盘 PVC → PV → 云资源 ID → 团队 删除 Pod 后就停止算保留磁盘费用
Ingress/LB/NAT 独享直接归属,共享按约定指标 用全部容器网络字节替代计费流量
控制平面/监控/日志 公共成本清单 将公共 Pod 同时计入团队直接成本和共享池
RDS/S3 等外部资源 云资源标签和独立账单映射 误以为 OpenCost 自动覆盖全部云资源
未分配磁盘/闲置节点 单列并指定责任人 只展示有 Pod 的资源导致漏账

7.3 一个完整月度示例#

假设已经完成同一币种、同一账期的真实账单对齐:

成本桶 金额
支付团队直接成本 ¥4,000
订单团队直接成本 ¥2,000
公共平台成本 ¥1,000
闲置成本 ¥2,000
总计 ¥9,000

按直接成本比例分摊公共成本,闲置由平台承担:

支付团队 = 4,000 + 1,000 × 4,000 / 6,000 = ¥4,666.67
订单团队 = 2,000 + 1,000 × 2,000 / 6,000 = ¥2,333.33
平台     = ¥2,000
合计     = ¥9,000

若所有团队直接成本都是零,不能除以零,应按预先约定由平台承担或固定权重分配。金额计算使用 Decimal 等十进制类型,并指定最后一分钱的舍入归属。若已启用工具的闲置分摊,后处理不能再次分摊同一笔闲置。

月度闭环必须能解释:真实账单 = 团队结算 + 平台承担 + 未归属 + 已说明的对账差异。税费、退款、账单延迟和汇率差异要有单独规则,而不是通过篡改资源核时凑平。

8. 验收实验与看板#

8.1 可控工作负载#

保存为 cost-demo.yaml,演示容器只 sleep,用于观察低使用、高申请的差异:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cost-demo
  namespace: payment-prod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cost-demo
  template:
    metadata:
      labels:
        app: cost-demo
        team: payment
        environment: prod
    spec:
      containers:
        - name: sleeper
          image: busybox:1.37.0
          command: ["sh", "-c", "sleep 86400"]
          resources:
            requests:
              cpu: "2"
              memory: 256Mi
            limits:
              cpu: "2"
              memory: 512Mi
kubectl apply -f cost-demo.yaml
kubectl -n payment-prod rollout status deployment/cost-demo --timeout=120s
kubectl -n payment-prod get pods -l app=cost-demo -o wide

记录真正开始 Running 的时间,保持 30 分钟,然后删除:

kubectl -n payment-prod delete deployment cost-demo

该 Pod 在稳定运行的 30 分钟内,CPU request 约贡献 2 × 0.5 = 1 核时,内存 request 约贡献 0.25 × 0.5 = 0.125 GiB 时;实际 CPU 消耗应很低。指标积分存在边界误差,检查对应 Pod 或测试前后 Namespace 增量,不应将 Namespace 中其他工作负载算进实验。

8.2 上线前验收表#

实验 验收点
固定 requests 运行 30 分钟 申请核时接近理论值,偏差能由采样边界解释
1 副本扩成 3 副本 request 曲线约变为原来 3 倍,核时按分段累计
容器重启 counter 重置后没有负费用或巨大尖峰
删除 Pod 后查询历史 已结束工作负载仍在历史日报中
短 Job 明确是否漏采,不能宣称分钟采样完全覆盖
不带归属的 Namespace 出现在未归属项中,不被丢弃
停止抓取 日报质量标记为不完整,而不是费用突然归零
同一日报重复导出 固定窗口结果可核对,后处理不会重复入账
月末对账 同范围同币种金额闭环,剩余差异有解释

试点可以先约定长时稳定负载积分误差目标,例如不超过 5%,这只是内部验收目标,不是工具保证;短任务需另设口径。

Grafana 建议展示:团队/月累计费用、日趋势、CPU request 核时与实际核时、内存 request 与 working set、公共成本、闲置成本、未归属成本、预算消耗、采集缺口。团队管理员看自己的明细,平台看跨团队全貌;日报输出不能替代访问隔离。

9. 常见问题与推广顺序#

问题 排查方向
OpenCost 没数据 Prometheus 地址、ServiceMonitor 选择器、网络和必需指标
成本为零或异常低 节点价格缺失、采集时间太短、状态未覆盖、短任务漏采
核时翻倍 cAdvisor 重复抓取、HA 副本重复计算、多集群未区分
namespace 有费用但没有 team 没有归属映射,或误认为标签会自动继承
PromQL 与 OpenCost 不一致 request/usage/allocation 口径、状态、分辨率、窗口不一致
云账单明显大于 OpenCost 折扣口径、外部服务、控制平面、网络、保留磁盘及遗漏节点
历史账单无法重算 指标已过期、未持久化、归属表或价格规则没有版本

推荐按四步推广:先完成 Namespace 归属与采集验收;再出团队资源日报;接着加入价格、公共和闲置成本并完成一个完整账期对账;最后由财务与团队共同确认后启用内部结算。财务确定价格和共享规则,平台负责数据完整性,团队负责 requests 合理性和归属准确性。

停用试点时,只删除本次创建的测试 Deployment 和记录规则;共享监控、业务 Namespace 及其 PVC 不应作为测试清理目标。原始日报与结算依据按约定留存。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭