GCP CUD kupiony ale billing nadal pokazuje stawki on-demand
Diagnoza niedziałającego GCP CUD: weryfikacja machine family, regionu, typu commitment (compute vs memory-optimized), sprawdzenie billing export i naprawa.
Ten runbook opisuje diagnozę i naprawę sytuacji, w której zakupiony GCP CUD nie jest naliczany na uruchomionych instancjach. Szczegółowe omówienie strategii CUD, Spot VMs i praktyk FinOps znajdziesz w artykule Optymalizacja kosztów GCP - Committed Use Discounts, Spot VMs i strategie FinOps. Jeśli potrzebujesz pomocy z doborem i optymalizacją commitmentów - umów konsultacje.
Objaw
Billing report pokazuje stawki on-demand mimo aktywnego commitment. Kredyty CUD nie pojawiają się w eksporcie rozliczeniowym:
# Lista aktywnych commitmentów w projekcie
gcloud compute commitments list \
--project=my-project \
--format="table(name, region, status, plan, resources[].type, resources[].amount, startTimestamp, endTimestamp)"
# Sprawdź status konkretnego commitmentu
gcloud compute commitments describe my-cud-commitment \
--region=us-central1 \
--project=my-project \
--format="yaml(name, status, plan, resources, type, startTimestamp, endTimestamp, category)"
# Zweryfikuj running instances i ich machine type
gcloud compute instances list \
--project=my-project \
--format="table(name, zone, machineType.basename(), status)" \
--filter="status=RUNNING"
Zapytanie do BigQuery billing export weryfikujące obecność kredytów CUD:
-- Sprawdź czy CUD credits pojawiają się w billing export
SELECT
invoice.month,
sku.description,
service.description,
SUM(cost) AS total_cost,
SUM((SELECT SUM(c.amount) FROM UNNEST(credits) c WHERE c.type = 'COMMITTED_USE_DISCOUNT')) AS cud_credits,
SUM((SELECT SUM(c.amount) FROM UNNEST(credits) c WHERE c.type = 'COMMITTED_USE_DISCOUNT_DOLLAR_BASE')) AS cud_dollar_credits
FROM `my-billing-project.billing_export.gcp_billing_export_v1_XXXXXX`
WHERE
service.description = 'Compute Engine'
AND usage_start_time >= TIMESTAMP('2026-07-01')
AND project.id = 'my-project'
GROUP BY 1, 2, 3
HAVING total_cost > 0
ORDER BY total_cost DESC
LIMIT 20;
Jeśli kolumny cud_credits i cud_dollar_credits zwracają NULL lub 0 dla SKU objętych commitmentem - CUD nie jest aplikowany.
Przyczyna
GCP CUD jest automatycznie aplikowany do pasujących zasobów, ale muszą być spełnione wszystkie kryteria jednocześnie. Najczęstsze przyczyny braku naliczenia:
-
Niezgodność machine family - CUD zakupiony dla rodziny N2 nie pokrywa instancji E2, N1 ani N2D. Commitment typu
GENERAL_PURPOSEpokrywa tylko konkretną rodzinę maszyn wskazaną przy zakupie. Częsty błąd: zakup CUD na N2 a uruchamianie workloadów na E2 (bo są tańsze per-vCPU on-demand). -
Niezgodność regionu - CUD jest powiązany z konkretnym regionem GCP. Commitment zakupiony w
us-central1nie pokrywa instancji uruchomionych weurope-west1. Nie ma mechanizmu cross-region CUD - każdy region wymaga oddzielnego commitment. -
Niezgodność typu commitment - CUD typu
COMPUTE_OPTIMIZED(rodzina C2/C2D) nie pokrywa workloadów general-purpose (N2/E2). Analogicznie CUDMEMORY_OPTIMIZED(M1/M2) pokrywa wyłącznie instancje memory-optimized. -
CUD jeszcze nieaktywny - po zakupie commitment przechodzi przez stan
CREATINGzanim stanie sięACTIVE. Może to trwać do 24 godzin. Billing credits zaczynają być naliczane dopiero od momentu aktywacji. -
Sole-tenant nodes - instancje uruchomione na sole-tenant nodes nie są pokrywane standardowymi CUD. Wymagają oddzielnego commitment typu sole-tenant.
-
Commitment wyczerpany - jeśli suma vCPU/RAM uruchomionych instancji przekracza zakupiony commitment, nadwyżka jest rozliczana on-demand. CUD pokrywa zasoby do limitu zakupionej ilości.
Rozwiązanie
A) Weryfikacja zgodności commitment z uruchomionymi instancjami:
# Szczegóły zakupionego CUD - machine type family i zasoby
gcloud compute commitments describe my-cud-commitment \
--region=us-central1 \
--project=my-project \
--format="json(name, status, resources, type, category)"
# Wynik powinien pokazać np.:
# "resources": [
# { "type": "VCPU", "amount": "32" },
# { "type": "MEMORY", "amount": "131072" } <- MB
# ]
# "type": "GENERAL_PURPOSE_N2"
# "category": "MACHINE"
# Porównaj z running instances - filtruj po machine family
gcloud compute instances list \
--project=my-project \
--filter="status=RUNNING AND machineType~'n2-'" \
--format="table(name, zone, machineType.basename())"
# Policz łączne vCPU instancji N2 w regionie us-central1
gcloud compute instances list \
--project=my-project \
--filter="status=RUNNING AND zone~'us-central1' AND machineType~'n2-'" \
--format="value(machineType.basename())" | \
awk -F'-' '{sum += $NF} END {print "Total vCPU (N2, us-central1):", sum}'
# Porównaj z commitmentem:
# Jeśli commitment = 32 vCPU, a running instances mają 48 vCPU
# -> 32 vCPU pokryte CUD, 16 vCPU rozliczane on-demand
B) Migracja instancji do pasującej machine family:
Jeśli commitment jest na N2, a instancje działają na E2 - zmień machine type:
# Zatrzymaj instancję przed zmianą machine type
gcloud compute instances stop my-instance \
--zone=us-central1-a \
--project=my-project
# Zmień machine type z E2 na N2 (zachowując podobną konfigurację)
# e2-standard-4 (4 vCPU, 16 GB) -> n2-standard-4 (4 vCPU, 16 GB)
gcloud compute instances set-machine-type my-instance \
--machine-type=n2-standard-4 \
--zone=us-central1-a \
--project=my-project
# Uruchom instancję ponownie
gcloud compute instances start my-instance \
--zone=us-central1-a \
--project=my-project
# Dla MIG (Managed Instance Group) - zaktualizuj instance template
gcloud compute instance-templates create my-template-n2-v2 \
--machine-type=n2-standard-4 \
--image-family=debian-12 \
--image-project=debian-cloud \
--project=my-project
gcloud compute instance-groups managed set-instance-template my-mig \
--template=my-template-n2-v2 \
--zone=us-central1-a \
--project=my-project
# Rolling update MIG do nowego template
gcloud compute instance-groups managed rolling-action start-update my-mig \
--version=template=my-template-n2-v2 \
--zone=us-central1-a \
--max-surge=1 \
--max-unavailable=0 \
--project=my-project
C) Zakup dodatkowego CUD w prawidłowym regionie/family:
# Sprawdź dostępne typy CUD dla regionu
gcloud compute commitments create-help
# Zakup CUD dla E2 w europe-west1 (jeśli tam działają instancje)
gcloud compute commitments create cud-e2-europe-west1 \
--region=europe-west1 \
--project=my-project \
--plan=twelve-month \
--resources=vcpu=16,memory=65536 \
--type=GENERAL_PURPOSE_E2
# Zakup CUD typu compute-optimized (C2) jeśli workload wymaga C2
gcloud compute commitments create cud-c2-us-central1 \
--region=us-central1 \
--project=my-project \
--plan=thirty-six-month \
--resources=vcpu=64,memory=262144 \
--type=COMPUTE_OPTIMIZED_C2D
Uwaga: Przed zakupem dodatkowego CUD upewnij się, że istniejący commitment nie jest wystarczający. Sprawdź utilization za pomocą rekomendacji w Billing → Commitments.
D) Flex CUD dla scenariuszy multi-region:
Jeśli workloady zmieniają regiony (np. DR failover, seasonal migration) - rozważ podejście z wieloma krótszymi commitmentami:
# GCP nie oferuje oficjalnie "Flex CUD" - ale można stosować strategię:
# 1. Mniejsze commitmenty per-region zamiast jednego dużego
# 2. Monitorowanie utilization i dokupywanie w miarę potrzeb
# Sprawdź rekomendacje CUD od Google (Billing -> Commitments -> Recommendations)
gcloud billing budgets list --billing-account=XXXXXX-XXXXXX-XXXXXX
# Alternatywnie - BigQuery query na billing export do analizy coverage
SELECT
location.region,
sku.description,
SUM(usage.amount_in_pricing_units) AS total_usage,
SUM(cost) AS total_cost,
SUM((SELECT SUM(c.amount) FROM UNNEST(credits) c WHERE c.type = 'COMMITTED_USE_DISCOUNT')) AS cud_applied
FROM `my-billing-project.billing_export.gcp_billing_export_v1_XXXXXX`
WHERE
service.description = 'Compute Engine'
AND usage_start_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
AND sku.description LIKE '%Instance Core%'
GROUP BY 1, 2
ORDER BY total_cost DESC;
Walidacja
Po wdrożeniu zmian zweryfikuj, że CUD credits zaczynają się pojawiać:
-- BigQuery: potwierdź naliczanie CUD credits w bieżącym dniu
SELECT
usage_start_time,
sku.description,
cost AS gross_cost,
(SELECT SUM(c.amount) FROM UNNEST(credits) c WHERE c.type = 'COMMITTED_USE_DISCOUNT') AS cud_credit,
cost + IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c WHERE c.type = 'COMMITTED_USE_DISCOUNT'), 0) AS net_cost
FROM `my-billing-project.billing_export.gcp_billing_export_v1_XXXXXX`
WHERE
service.description = 'Compute Engine'
AND project.id = 'my-project'
AND usage_start_time >= TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), DAY)
AND sku.description LIKE '%N2%Instance Core%'
ORDER BY usage_start_time DESC
LIMIT 20;
-- Expected: cud_credit < 0 (ujemna wartość = naliczony rabat)
# Potwierdź utilization commitment
gcloud compute commitments list \
--project=my-project \
--region=us-central1 \
--format="table(name, status, resources[].type, resources[].amount)"
# Sprawdź w Billing API commitment coverage
gcloud billing accounts describe XXXXXX-XXXXXX-XXXXXX \
--format="json"
# Zweryfikuj brak instancji poza pokryciem CUD (on-demand spillover)
gcloud compute instances list \
--project=my-project \
--filter="status=RUNNING AND zone~'us-central1'" \
--format="table(name, machineType.basename())" | \
grep -v "n2-" | grep -v "NAME"
# Expected: pusta lista (wszystkie instancje w regionie to N2 pokryte CUD)
Pełna walidacja finansowa - porównaj koszt bieżącego miesiąca z poprzednim:
-- Porównanie kosztów month-over-month z widocznością CUD
SELECT
FORMAT_TIMESTAMP('%Y-%m', usage_start_time) AS month,
SUM(cost) AS gross_cost,
SUM((SELECT SUM(c.amount) FROM UNNEST(credits) c WHERE c.type = 'COMMITTED_USE_DISCOUNT')) AS cud_savings,
SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c WHERE c.type = 'COMMITTED_USE_DISCOUNT'), 0)) AS net_cost
FROM `my-billing-project.billing_export.gcp_billing_export_v1_XXXXXX`
WHERE
service.description = 'Compute Engine'
AND project.id = 'my-project'
AND usage_start_time >= TIMESTAMP('2026-06-01')
GROUP BY 1
ORDER BY 1;
-- Expected: net_cost w bieżącym miesiącu niższy o ~30-57% vs on-demand baseline
CUD nie obniża rachunku za GCP?
Umów bezpłatną 30-minutową rozmowę. Przeanalizujemy Twoje commitmenty, zidentyfikujemy luki w pokryciu i dobierzemy optymalną strategię CUD dla Twojej infrastruktury.