Connect Kubernetes
Connect Kubernetes
Costfluent distributes the cost of a Kubernetes cluster's nodes across namespaces and shows the remaining idle cost. It does not offer a verified per-pod, workload or container cost view. A small agent, installed with Helm, reads resource usage inside the cluster and reports it to Costfluent every hour. There is no connection to create first: the cluster registers itself on its first report and appears under Settings, then Integrations, then Kubernetes.
Requirements
- A Kubernetes cluster you can install a Helm chart into, with cluster-wide read access for the agent's service account.
- Outbound HTTPS from the cluster to
https://api.costfluent.com, directly or through a proxy. - An organization API token with the Report Kubernetes usage capability. Workspace tokens are refused.
Install the agent
Open Settings, then API tokens, and create an organization token with only the Report Kubernetes usage capability. That capability allows the one upload the agent makes and nothing else. Copy the token; its full value is shown only once.
Pick a cluster ID. It names the cluster in Costfluent and must be unique within your organization: 1 to 63 letters, digits, dots, underscores or hyphens, starting with a letter or digit. Then install the chart:
Code
Install one agent per cluster. Within a few minutes the cluster shows on the Kubernetes page as Importing. Enable it in the workspaces that should see its cost, as with any other data source.
Key values
| Value | Default | Purpose |
|---|---|---|
agent.token | none | The organization API token. Set it, or agent.secret. |
agent.secret.name, agent.secret.key | none | An existing Secret holding the token, instead of agent.token. |
agent.clusterID | none, required | The cluster's ID in Costfluent. |
agent.apiEndpoint | https://api.costfluent.com | Where reports go. |
agent.pollingInterval | Seconds between usage samples: 5, 10, 15, 30 or 60. | |
agent.nodeAddressTypes | Which node address the agent uses to reach each kubelet. | |
agent.disableKubeTLSverify | false | Skip verifying kubelet certificates. |
agent.allowedLabels | all | Pod labels to send. Empty sends every pod label. |
agent.allowedAnnotations | none | Pod annotations to send. Empty sends none. |
agent.collectNamespaceLabels | false | Send namespace labels. |
agent.reportHTTPProxy | none | An HTTP proxy for the upload. |
persist.size, persist.storageClassName | 1Gi | The volume that buffers reports while Costfluent cannot be reached. |
resources | requests 50m CPU and 64Mi, limit 256Mi | CPU and memory requests and limits for the agent. |
Keep the token out of your values files in source control: store it in a Secret and point
agent.secret at it.
Sizing
The agent is one pod, whatever the size of the cluster. Its memory grows with the number of
containers it tracks. Measured with 61 pods at a 5 second polling interval, its working set
averaged 11.4 MiB with a 12.8 MiB peak, using under 0.001 CPU cores. The defaults (64Mi
requested, 256Mi limit) leave room for clusters many times that size; raise the memory limit if
the pod is restarted for exceeding it.
What is read and sent
The agent only reads: nodes, pods, namespaces, and the resource metrics each kubelet serves. It sends node shape and identity, pod and container identity, resource requests and usage, and the pod labels you allow. It never sends container images, environment variables, secrets, config maps, logs or network traffic. The chart README's table of what the agent reads and sends is the complete list.
Reports that cannot be delivered are kept on the agent's volume and sent once Costfluent is reachable again.
How costs are calculated
Each node's cost for the day is split into CPU, memory and, on GPU nodes, GPU. The calculation uses
container resource requests and measured usage to distribute cost to namespaces. The part of a
node's cost that remains unallocated is idle cost, and appears as the namespace
__idle__.
A node's price comes from the first of these that has one:
- The billing rows of an AWS, Azure or GCP connection in your organization that bill that node.
- The node's own annotations, described below.
- The rates set for the cluster in Costfluent.
A node none of them prices is left out and counted as unpriced on the cluster.
Costfluent processes each cluster once a night, at 02:00 UTC, for the previous day. Cost therefore
appears the morning after the agent is installed, while the Kubernetes page shows the latest
report within minutes. In Cost Reports, group or filter by Cluster and Namespace, and use
pod labels as tags named k8s:label:<key>.
On-premises and custom rates
For nodes without cloud billing, such as on-premises or bare-metal clusters, open the cluster on the Kubernetes page and set its hourly rates per vCPU, per GB of memory and per GPU, and their currency. To price individual nodes differently, annotate them:
Code
Annotation rates are read in the cluster's currency and take precedence over the cluster's rates.
Avoid double counting
A cluster's cost is the cost of its nodes, which the cloud connection that pays for them already reports. Costfluent does not count Kubernetes cost toward tracked spend, but a Cost Report over a workspace that holds both sources shows the nodes twice: once as the cloud's instances, once allocated to namespaces. Filter a report to one side, by provider, when you want a total.
Cluster statuses
| Status | Meaning |
|---|---|
| Importing | The cluster has reported, and its first day has not been processed yet. |
| Stable | Reports arrive and each day is processed. |
| Stale | No report for two hours. Check that the agent pod is running and can reach Costfluent. |
| Warning | Some nodes have no price, or processing a day failed. The cluster page says which. |
Troubleshooting
The agent logs every refused upload with the reason. The common ones:
- 401 or 403. The token is wrong, revoked, a workspace token, or lacks the Report Kubernetes usage capability. Reports stay buffered, so fixing the token recovers them.
- 409. Another agent already reports this cluster ID, or the organization has reached its limit of 100 clusters. Give each cluster its own ID.
- 410. The cluster was deleted in Costfluent. Uninstall the agent, or install it again under a new cluster ID.
- 413. A report was too large. The agent backs off and retries; limit
agent.allowedLabelsif it persists. - No usage on AKS. Kubelets on AKS often serve certificates the agent cannot verify, or are
not reachable at their default address. Set
agent.disableKubeTLSverify=trueandagent.nodeAddressTypes=InternalIP.
Uninstall
Code
The cluster turns Stale two hours later and its past cost stays in Cost Reports. Delete it on the Kubernetes page to remove it; an agent still running for a deleted cluster is refused. Then revoke its API token.