Kubernetes is where cloud cost attribution goes to die. The cloud bill sees nodes; the teams live in namespaces; and the mapping between the two is invisible to AWS Cost Explorer. Until you solve that, every Kubernetes platform is a shared cost nobody owns, which means it grows unchecked.
Requests, usage, or the max of both
The first real decision is what you bill teams on. Charging on actual usage rewards teams that under-request and then starve their neighbours at peak. Charging on requests rewards padding. We almost always allocate on the maximum of request and usage per workload - you pay for what you reserved or what you used, whichever is higher. It is the only model that makes both over-requesting and noisy-neighbour behaviour visible on someone's bill.
- Allocate node cost down to pods by the max(request, usage) of CPU and memory
- Split idle/unallocated node capacity explicitly - do not silently spread it
- Attribute shared add-ons (ingress, monitoring, CoreDNS) by a documented key
- Keep storage (PVs) and load balancer cost separate - they do not follow pod CPU
Tooling: Kubecost or OpenCost, plus the cloud bill
We deploy OpenCost or Kubecost to map pod-level resource consumption to real cloud prices, then reconcile the total against the actual CUR every month. The reconciliation matters: in-cluster tools estimate node cost, and if you do not tie them back to the bill you drift. We aim to keep the gap under 5%.
Idle capacity is the most political number in the cluster. Decide who owns it before anyone sees the report, not after.
Who pays for idle?
A cluster running at 40% utilization has 60% unallocated. Hiding that by spreading it across teams punishes efficient teams and lets the platform off the hook. We surface idle as a line the platform team owns, which gives them the incentive to fix bin-packing, tune the cluster autoscaler, and adopt Karpenter-style consolidation.
kubectl cost namespace \
--window 30d \
--show-cpu --show-memory --show-efficiencyShip showback before chargeback
We never start with chargeback in Kubernetes. We publish per-namespace showback for two or three months first, let teams argue with the numbers, fix the allocation rules they poke holes in, and only then talk about moving budget. A model nobody trusts is worse than no model. The payoff is concrete: once teams see their namespace cost and their efficiency percentage side by side, requests get trimmed, and a typical cluster recovers 25-40% of its waste in the first quarter without anyone mandating it from above.