fix: prevent duplicate cluster-scoped metrics with --namespaces#2923
fix: prevent duplicate cluster-scoped metrics with --namespaces#2923vigneshakaviki wants to merge 1 commit into
Conversation
…mespaces When using --namespaces to filter by specific namespaces, cluster-scoped resources (nodes, PVs, namespaces, clusterroles, etc.) were creating one store per namespace. Since cluster-scoped resources ignore the namespace parameter, each store watched all objects, producing N duplicate copies of every metric (where N = number of specified namespaces). Add buildClusterScopedStores() that always creates a single store with NamespaceAll, and use it for all cluster-scoped resource build functions: nodes, persistentvolumes, storageclasses, namespaces, clusterroles, clusterrolebindings, mutatingwebhookconfigurations, validatingwebhookconfigurations, volumeattachments, certificatesigningrequests, and ingressclasses. Fixes kubernetes#2878 Signed-off-by: Vignesh <kumarvignesh295@gmail.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: vigneshakaviki The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
This issue is currently awaiting triage. If kube-state-metrics contributors determine this is a relevant issue, they will accept it by applying the The DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
Welcome @vigneshakaviki! |
|
Invalid commit message issues detected Invalid commit messagesKeywords which can automatically close issues and hashtag(#) mentions are not allowed.
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
There was a problem hiding this comment.
Pull request overview
Fixes duplicate metric series emitted for cluster-scoped resources when --namespaces is set by ensuring cluster-scoped collectors create only a single store/reflector (watching NamespaceAll) instead of one per provided namespace.
Changes:
- Updated cluster-scoped resource store builders to use a new
buildClusterScopedStores()helper. - Added
buildClusterScopedStores()which always creates exactly one store usingNamespaceAll, avoiding per-namespace duplication.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| metricFamilies = generator.FilterFamilyGenerators(b.familyGeneratorFilter, metricFamilies) | ||
| composedMetricGenFuncs := generator.ComposeMetricGenFuncs(metricFamilies) | ||
| familyHeaders := generator.ExtractMetricFamilyHeaders(metricFamilies) | ||
|
|
||
| store := metricsstore.NewMetricsStore( | ||
| familyHeaders, | ||
| composedMetricGenFuncs, | ||
| ) | ||
| if b.fieldSelectorFilter != "" { | ||
| klog.InfoS("FieldSelector is used", "fieldSelector", b.fieldSelectorFilter) | ||
| } | ||
| listWatcher := listWatchFunc(b.kubeClient, v1.NamespaceAll, b.fieldSelectorFilter) | ||
| b.startReflector(expectedType, store, listWatcher, useAPIServerCache, objectLimit, b.kubeClient) | ||
| return []cache.Store{store} |
| // buildClusterScopedStores creates a single store for cluster-scoped resources | ||
| // (e.g., nodes, PVs, namespaces, clusterroles). Unlike buildStores, this | ||
| // always watches all objects regardless of the --namespaces flag, preventing | ||
| // duplicate metrics when multiple namespaces are specified. |
Summary
Fixes #2878
When using
--namespacesto filter by specific namespaces, cluster-scoped resources (nodes, PVs, namespaces, clusterroles, etc.) were creating one store per namespace. Since cluster-scoped resources ignore the namespace parameter in the list/watch call, each store watched all objects, producing N duplicate copies of every metric (where N = number of specified namespaces).This caused Prometheus warnings like:
Root Cause
buildStores()iterates overb.namespacesto create one store per namespace. This is correct for namespace-scoped resources (pods, services, deployments, etc.) but wrong for cluster-scoped resources (nodes, PVs, namespaces, clusterroles, etc.) which don't have a namespace dimension.Fix
Added
buildClusterScopedStores()that always creates a single store withNamespaceAll, bypassing the per-namespace loop. Updated all cluster-scoped resource build functions to use it:nodespersistentvolumesstorageclassesnamespacesclusterrolesclusterrolebindingsmutatingwebhookconfigurationsvalidatingwebhookconfigurationsvolumeattachmentscertificatesigningrequestsingressclassesNamespace-scoped resources continue using
buildStoresFuncas before.Local Verification (minikube,
--namespaces=default,kube-system --resources=nodes)Before (stock binary) — duplicate metrics
Each node metric appears 2 times (once per namespace), identical values:
After (patched binary) — no duplicates
Each node metric appears exactly once:
Namespace-scoped resources unaffected
Pods are still correctly filtered per namespace with zero duplicates:
Test Plan
TestCronJobStorefailure on main)