feat(monitoring-agents): export PVC labels from kube-state-metrics (#5215)

## What this PR does

Adds `persistentvolumeclaims=[*]` to the kube-state-metrics
`--metric-labels-allowlist`, next to the existing `pods=[*]` and
`deployments=[*]`. kube-state-metrics then publishes
`kube_persistentvolumeclaim_labels`, one series per PVC, with the PVC's
labels as `label_*`.

Why: the per-application metrics scope in the design proposal [Tenant
resource-consumption
metrics](https://github.com/cozystack/community/pull/94) (Phase 0) finds
an application's volumes through the `apps.cozystack.io/application.*`
lineage labels on its PVCs. Without this series, volume usage
(`kubelet_volume_stats_*`, which carries `persistentvolumeclaim` but not
`pod`) cannot be attributed to an application.

`[*]` rather than an explicit key list: kube-state-metrics has no prefix
matching, so the three lineage keys would have to be enumerated, and the
series count is the same either way (one per PVC). `[*]` stays
consistent with the existing pods and deployments entries and does not
silently miss a lineage key added later. PVCs are far fewer than pods,
which already export all labels.

#### How it was tested

- helm-unittest for `monitoring-agents`: a new suite asserts the exact
flag in the rendered kube-state-metrics Deployment.
- Verified on a test cluster: `kube_persistentvolumeclaim_labels` is
present and carries `label_apps_cozystack_io_application_name`.
- Not verified: the memory impact on kube-state-metrics.

#### Known limitation

PVCs created from a StatefulSet's `volumeClaimTemplates` usually have no
owner reference and no Flux label, so the lineage webhook gives them no
lineage labels and this series cannot attribute them to an application.
Fixing that belongs to the lineage webhook.

### Screenshots

No UI changes.

### Downstream repositories

- [ ] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

Downstream: no trigger matched. Candidate: none affected, because the
diff touches only `packages/system/monitoring-agents/values.yaml` and a
test in that system package; it adds a series but renames no telemetry
metric, platform value, app field or CRD.

### Release note

```release-note
feat(monitoring-agents): kube-state-metrics now exports PVC labels as `kube_persistentvolumeclaim_labels`, one series per PVC, so volume usage can be attributed to the application that owns it.
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

<!-- coderabbit-ai-generated:v1 -->

## Summary by CodeRabbit

* **New Features**
* Kubernetes monitoring metrics now include labels from pods,
deployments, and persistent volume claims. This expands the resource
metadata available alongside metrics, including lineage labels used by
the tenant metrics API. Metrics for these resource labels are emitted
only for resources covered by the configured label allowlist.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Aleksei Sviridkin authored and GitHub committed 2026-11-04 18:22:09 +03:00
commit e2283b3758
2 files changed
+25 -4

No files matched your search

@@ -0,0 +1,15 @@
suite: kube-state-metrics exports the labels of pods, deployments and PVCs
# The tenant metrics API scopes a query to one application by looking up the
# application's pods and PVCs in kube_pod_labels and
# kube_persistentvolumeclaim_labels by their apps.cozystack.io/application.*
# lineage labels. kube-state-metrics emits no kube_*_labels series at all for
# a resource missing from this allowlist, so dropping persistentvolumeclaims
# silently empties the PVC branch of that lookup.
templates:
- charts/kube-state-metrics/templates/deployment.yaml
tests:
- it: allowlists all labels of pods, deployments and persistentvolumeclaims
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: --metric-labels-allowlist=pods=[*],deployments=[*],persistentvolumeclaims=[*]
+10 -4
View File
@@ -6,9 +6,10 @@ kube-state-metrics:
# 322 pods and roughly 25.6k series, which is the smallest cluster we run. The
# request sits above the 176Mi mean rather than at the peak, and the limit
# carries wide headroom on purpose: this component's memory scales with the
# number of objects in the cluster, and --metric-labels-allowlist below widens
# every pod and deployment series further, so a cluster larger than the one
# measured will land well above the peak seen here.
# number of objects in the cluster, and --metric-labels-allowlist below copies
# every label of each pod, deployment and PVC onto its kube_*_labels series,
# so a cluster larger than the one measured will land well above the peak
# seen here.
# 2Gi is 6.7x that peak, so scaling linearly with object count it stays a
# ceiling rather than a bound up to roughly 2100 pods and 170k series.
#
@@ -27,7 +28,12 @@ kube-state-metrics:
limits:
memory: 2Gi
extraArgs:
- --metric-labels-allowlist=pods=[*],deployments=[*]
# PVCs are listed so the tenant metrics API can find an application's PVCs
# in kube_persistentvolumeclaim_labels by their apps.cozystack.io/application.*
# lineage labels. kube-state-metrics emits that metric only for resources on
# this list, one series per PVC; naming only the lineage keys would emit the
# same number of series.
- --metric-labels-allowlist=pods=[*],deployments=[*],persistentvolumeclaims=[*]
rbac:
extraRules:
- apiGroups: