gke-cost-analysis

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GKE Cost Analysis

GKE成本分析

This skill provides guidance on answering natural language questions about GKE-related costs, billing reports, and utilization analysis.
本技能提供关于GKE相关成本、账单报告及利用率分析的自然语言问题解答指导。

Overview

概述

When users ask about GKE costs (e.g., "What are my costs across projects?", "What's my most expensive namespace?", "Why is my cluster cost spiking?"), use this skill to provide a structured and expert response using BigQuery billing exports, cost allocation metadata, and live cluster metrics.
当用户询问GKE相关成本问题(例如:"我的跨项目成本是多少?"、"我成本最高的命名空间是哪个?"、"为什么我的集群成本突然飙升?")时,可借助本技能,通过BigQuery账单导出数据、成本分配元数据和集群实时指标,提供结构化的专业回复。

Instructions

操作说明

When handling a cost-related question:
  1. Provide a Direct Answer: Address the specific cost question or analytical request clearly and concisely.
  2. Explain BigQuery Integration: Explain how to query BigQuery for historical cost breakdown. Note that GKE costs originate from the GCP Billing Detailed BigQuery Export (
    gcp_billing_export_resource_v1_*
    ).
  3. Check & Verify Cost Allocation: Explain that GKE Cost Allocation must be enabled on the cluster (
    --enable-cost-allocation
    ) for namespace, label, and workload-level billing granularity. If queries return empty labels, provide the
    gcloud
    command to enable it.
  4. Analyze Pricing Drivers & Utilization: When diagnosing cost drivers, explain whether the cluster is in Autopilot (billed by requested pod CPU/memory) or Standard mode (billed by underlying VM node size + control plane fees), and compare live utilization (
    kubectl top
    ) against provisioned requests.
  5. Provide Actionable Commands/Queries: Provide concrete BigQuery CLI (
    bq query
    ) commands or read-only
    gcloud
    /
    kubectl
    inspection commands. Prefer
    bq
    over BigQuery Studio when available.
处理成本相关问题时:
  1. 直接解答:清晰、简洁地回应特定成本问题或分析请求。
  2. 解释BigQuery集成:说明如何查询BigQuery获取历史成本明细。注意GKE成本源自GCP账单详细BigQuery导出表(
    gcp_billing_export_resource_v1_*
    )。
  3. 检查并验证成本分配:解释必须在集群上启用GKE成本分配功能(
    --enable-cost-allocation
    ),才能获得命名空间、标签和工作负载级别的账单粒度。如果查询返回空标签,提供启用该功能的
    gcloud
    命令。
  4. 分析定价驱动因素与利用率:诊断成本驱动因素时,说明集群处于Autopilot模式(按Pod请求的CPU/内存计费)还是Standard模式(按底层VM节点规格+控制平面费用计费),并对比实时利用率(
    kubectl top
    )与已配置的资源请求量。
  5. 提供可执行命令/查询语句:提供具体的BigQuery CLI(
    bq query
    )命令或只读的
    gcloud
    /
    kubectl
    检查命令。若可用,优先使用
    bq
    而非BigQuery Studio。

Key Points & Pricing Drivers

核心要点与定价驱动因素

  • Data Source: GKE costs come from GCP Billing Detailed BigQuery Export. The user must provide the full path to their BigQuery table (dataset name and table name containing the Billing Account ID).
  • Granularity Requirement: GKE Cost Allocation (
    --enable-cost-allocation
    ) must be enabled on the cluster to populate
    goog-k8s-cluster-name
    ,
    k8s-namespace
    ,
    k8s-workload-name
    , and
    k8s-workload-type
    labels in BigQuery.
  • Autopilot vs. Standard Cost Drivers:
    • Autopilot Pricing: Billed directly on pod resource requests (
      requests.cpu
      ,
      requests.memory
      , ephemeral storage). Over-requested pods drive up billing regardless of whether the pod actively uses those CPU cycles or memory.
    • Standard Pricing: Billed on provisioned node pool VMs (
      e2
      ,
      n4
      ,
      c3
      , etc.) plus a cluster management fee ($0.10/hour). Idle nodes or multiple low-utilization dev clusters drive excess infrastructure costs.
  • Credits & Discounts Impact: When analyzing
    cost
    versus
    cost_before_credits
    , note that Committed Use Discounts (CUDs) and Spot VMs appear as credits or reduced rate charges in the billing export.
  • Tools & Syntax: BigQuery CLI (
    bq
    ) is preferred. When writing Standard SQL queries, use a dot (
    .
    ) instead of a colon (
    :
    ) to separate the project ID and dataset name (
    {project_id}.{dataset_name}.{table_name}
    ).
  • Defaults: Assume last 30 days, row limit 10, ordering by cost descending (
    ORDER BY cost DESC
    ), unless specified otherwise.
  • 数据源:GKE成本来自GCP账单详细BigQuery导出表。用户需提供BigQuery表的完整路径(包含账单账户ID的数据集名称和表名称)。
  • 粒度要求:必须在集群上启用GKE成本分配功能(
    --enable-cost-allocation
    ),才能在BigQuery中填充
    goog-k8s-cluster-name
    k8s-namespace
    k8s-workload-name
    k8s-workload-type
    标签。
  • Autopilot与Standard模式成本驱动差异
    • Autopilot定价:直接按Pod资源请求量(
      requests.cpu
      requests.memory
      、临时存储)计费。过度请求资源的Pod会推高账单,无论Pod是否实际使用这些CPU周期或内存。
    • Standard定价:按已配置的节点池VM(
      e2
      n4
      c3
      等)计费,外加集群管理费用(每小时0.10美元)。闲置节点或多个低利用率开发集群会导致基础设施成本浪费。
  • ** credits与折扣影响**:分析
    cost
    cost_before_credits
    时,需注意承诺使用折扣(CUDs)和Spot VM会在账单导出表中显示为credits或费率降低的费用。
  • 工具与语法:优先使用BigQuery CLI(
    bq
    )。编写标准SQL查询时,使用点(
    .
    )而非冒号(
    :
    )分隔项目ID和数据集名称(
    {project_id}.{dataset_name}.{table_name}
    )。
  • 默认设置:默认查询最近30天的数据,行限制为10,按成本降序排序(
    ORDER BY cost DESC
    ),除非用户另有指定。

Live Cluster & Cost Monitoring

集群实时监控与成本监控

Use read-only CLI commands to inspect current cluster budgets, node utilization, and pod resource consumption vs. requests:
bash
undefined
使用只读CLI命令检查当前集群预算、节点利用率以及Pod资源消耗与请求量的对比:
bash
undefined

View billing budgets for an account (requires Cost Management API)

查看账户的账单预算(需要Cost Management API)

gcloud billing budgets list --billing-account={billing_account} --quiet
gcloud billing budgets list --billing-account={billing_account} --quiet

Verify/Enable GKE cost allocation on a cluster for namespace-level billing tracking

验证/启用集群上的GKE成本分配功能,以跟踪命名空间级别的账单

gcloud container clusters update {cluster_name}
--enable-cost-allocation
--region {region}
gcloud container clusters update {cluster_name}
--enable-cost-allocation
--region {region}

View live node resource utilization across the cluster

查看集群中所有节点的实时资源利用率

kubectl top nodes
kubectl top nodes

View pod resource usage across namespaces (compare against requested limits to diagnose waste)

查看所有命名空间的Pod资源使用情况(与请求的限制对比以诊断资源浪费)

kubectl top pods --all-namespaces --containers
undefined
kubectl top pods --all-namespaces --containers
undefined

Applying Cost Optimizations

实施成本优化

To apply rightsizing changes based on analysis (such as setting up
VPA
recommendation mode, adjusting CPU/memory to
P95 * 1.2
, configuring Spot VMs via
nodeSelector
or
ComputeClass
, enforcing
ResourceQuotas
, or selecting machine types and CUDs), use the
gke-cost-optimization
skill.
若要基于分析结果实施资源调整变更(例如设置
VPA
推荐模式、将CPU/内存调整为
P95 * 1.2
、通过
nodeSelector
ComputeClass
配置Spot VM、强制执行
ResourceQuotas
,或选择机器类型和CUDs),请使用**
gke-cost-optimization
**技能。

Example BigQuery Queries

BigQuery查询示例

Use these queries as templates to answer questions. All parameters (dataset, table, project, cluster, etc.) must be replaced with user values.
可将以下查询作为模板来回答问题。所有参数(数据集、表、项目、集群等)必须替换为用户的实际值。

Cost of a Single Workload in a Single Cluster

单个集群中单个工作负载的成本

sql
bq query --nouse_legacy_sql '
SELECT
  SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c), 0)) AS cost,
  SUM(cost) AS cost_before_credits
FROM {billing_export_table} AS bqe
WHERE _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND project.id = "{project_id}"
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-location" AND l.value = "{region}")
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-name" AND l.value = "{cluster_name}")
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "k8s-namespace" AND l.value = "{namespace}")
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "k8s-workload-type" AND l.value = "{workload_type}")
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "k8s-workload-name" AND l.value = "{workload_name}")
;
'
sql
bq query --nouse_legacy_sql '
SELECT
  SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c), 0)) AS cost,
  SUM(cost) AS cost_before_credits
FROM {billing_export_table} AS bqe
WHERE _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND project.id = "{project_id}"
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-location" AND l.value = "{region}")
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-name" AND l.value = "{cluster_name}")
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "k8s-namespace" AND l.value = "{namespace}")
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "k8s-workload-type" AND l.value = "{workload_type}")
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "k8s-workload-name" AND l.value = "{workload_name}")
;
'

Cost of Each Workload in Each Cluster

每个集群中各工作负载的成本

sql
bq query --nouse_legacy_sql '
SELECT
  project.id AS project_id,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-location" LIMIT 1) AS cluster_location,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-name" LIMIT 1) AS cluster_name,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "k8s-namespace" LIMIT 1) AS k8s_namespace,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "k8s-workload-type" LIMIT 1) AS k8s_workload_type,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "k8s-workload-name" LIMIT 1) AS k8s_workload_name,
  SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c), 0)) AS cost,
  SUM(cost) AS cost_before_credits
FROM {billing_export_table} AS bqe
WHERE _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-name")
GROUP BY 1, 2, 3, 4, 5, 6
ORDER BY 7 DESC
LIMIT 10
;
'
sql
bq query --nouse_legacy_sql '
SELECT
  project.id AS project_id,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-location" LIMIT 1) AS cluster_location,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-name" LIMIT 1) AS cluster_name,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "k8s-namespace" LIMIT 1) AS k8s_namespace,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "k8s-workload-type" LIMIT 1) AS k8s_workload_type,
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "k8s-workload-name" LIMIT 1) AS k8s_workload_name,
  SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c), 0)) AS cost,
  SUM(cost) AS cost_before_credits
FROM {billing_export_table} AS bqe
WHERE _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-name")
GROUP BY 1, 2, 3, 4, 5, 6
ORDER BY 7 DESC
LIMIT 10
;
'

Cost Breakdown by Namespace in a Cluster

单个集群中按命名空间划分的成本明细

sql
bq query --nouse_legacy_sql '
SELECT
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "k8s-namespace" LIMIT 1) AS k8s_namespace,
  SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c), 0)) AS net_cost,
  SUM(cost) AS gross_cost
FROM {billing_export_table} AS bqe
WHERE _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND project.id = "{project_id}"
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-name" AND l.value = "{cluster_name}")
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10
;
'
Note: Checking that the
goog-k8s-cluster-name
label exists scopes the total billing data specifically to GKE costs.
sql
bq query --nouse_legacy_sql '
SELECT
  (SELECT l.value FROM bqe.labels AS l WHERE l.key = "k8s-namespace" LIMIT 1) AS k8s_namespace,
  SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c), 0)) AS net_cost,
  SUM(cost) AS gross_cost
FROM {billing_export_table} AS bqe
WHERE _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND project.id = "{project_id}"
  AND EXISTS(SELECT * FROM bqe.labels AS l WHERE l.key = "goog-k8s-cluster-name" AND l.value = "{cluster_name}")
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10
;
'
注意:检查
goog-k8s-cluster-name
标签是否存在,可将账单数据范围限定为GKE相关成本。