[CONTP-1569] [CONTINT-5553] Add podCollectionMode field on kubeStateMetricsCore for node-side pod collection - #3027
Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 6 commits intoAug 28, 2026
Conversation
|
🎯 Code Coverage (details) 🔗 Commit SHA: 3e30362 | Docs | View more details | Give us feedback! |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3027 +/- ##
==========================================
+ Coverage 41.50% 41.58% +0.07%
==========================================
Files 335 334 -1
Lines 28714 28795 +81
==========================================
+ Hits 11919 11975 +56
- Misses 16001 16019 +18
- Partials 794 801 +7
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
zhuminyi
force-pushed
the
minyi/ksm-pod-collection-on-node
branch
from
May 19, 2026 02:31
dcdead3 to
9c80b42
Compare
zhuminyi
marked this pull request as ready for review
May 19, 2026 02:51
AlexanderYastrebov
approved these changes
May 19, 2026
joepeeples
approved these changes
May 19, 2026
sblumenthal
reviewed
Jun 25, 2026
zhuminyi
force-pushed
the
minyi/ksm-pod-collection-on-node
branch
from
June 25, 2026 21:01
09a7e15 to
8d867c3
Compare
gh-worker-dd-mergequeue-cf854d Bot
pushed a commit
to DataDog/datadog-agent
that referenced
this pull request
Jul 8, 2026
…egates_only` check (#53042) ### What does this PR do? <img width="4452" height="1660" alt="image" src="https://github.com/user-attachments/assets/801431b2-f957-4441-a959-6f53c6b93cc3" /> Fixes under-reporting of the `kubernetes_state.{container}.<cpu|memory|gpu>_{requested,limit}.total` family when the KSM check runs in `pod_collection_mode: node_kubelet`. ### Motivation In `node_kubelet` mode every node agent computes the `.total` family from its *local* pod view and emits it with a **reduced tag set** —`[namespace, container, owner_kind, owner_name]`, with **no host/pod/node tag**. Because every node emits a byte-identical series at (roughly) the same timestamp, the backend's same-tags/same-timestamp collision rule keeps only **one** node's value. Result: the cluster aggregation metrics are total under-reported, sum does not work either. Count-style metrics (`pod.count`, etc.) are unaffected — they carry a `node` tag, so per-node series stay distinct and sum correctly. Only the tag-collapsed `.total` family breaks. A new `pod_collection_mode: cluster_aggregates_only` watches all** pods and emits only the `.total` family. It will be run on clc runner but aggregate just the 4 owner-tagged source metrics. ### Describe how you validated your changes Suppression is enabled per-instance via the `cluster_aggregates_enabled` KSM check option, set on the `node_kubelet` and `cluster_unassigned` instances (the `cluster_aggregates_only` instance omits it). For operator Datadog CR, related [PR](DataDog/datadog-operator#3027) ``` apiVersion: datadoghq.com/v2alpha1 kind: DatadogAgent metadata: name: datadog namespace: datadog spec: global: credentials: apiSecret: secretName: datadog-secret keyName: api-key features: kubeStateMetricsCore: enabled: true conf: configData: |- cluster_check: true init_config: instances: # non-pod resources + unassigned pods - skip_leader_election: true pod_collection_mode: cluster_unassigned cluster_aggregates_enabled: true - skip_leader_election: true pod_collection_mode: cluster_aggregates_only clusterChecks: enabled: true override: nodeAgent: extraConfd: configDataMap: kubernetes_state_core.yaml: |- init_config: instances: - collectors: - pods pod_collection_mode: node_kubelet cluster_aggregates_enabled: true ``` For Helm install ``` datadog: clusterChecks: enabled: true kubeStateMetricsCore: enabled: false # node agents → node_kubelet (scheduled pods) confd: kubernetes_state_core.yaml: |- init_config: instances: - collectors: - pods pod_collection_mode: node_kubelet cluster_aggregates_enabled: true clusterAgent: confd: kubernetes_state_core.yaml: |- cluster_check: true init_config: instances: - skip_leader_election: true pod_collection_mode: cluster_unassigned cluster_aggregates_enabled: true - skip_leader_election: true pod_collection_mode: cluster_aggregates_only ``` ### Additional Notes Co-authored-by: minyi.zhu <minyi.zhu@datadoghq.com>
Introduces features.kubeStateMetricsCore.podCollectionMode on the v2alpha1 DatadogAgent CRD (enum: default | node_kubelet). When set to node_kubelet, the operator: - injects pod_collection_mode: cluster_unassigned into the operator-generated cluster-side KSM ConfigMap (skipped when the user supplies their own .Conf override; the operator never mutates user-supplied YAML); - generates a second ConfigMap with a pods-only check (pod_collection_mode: node_kubelet, collectors: [pods]); - mounts that ConfigMap into every node agent (multi-container and single-container) at /etc/datadog-agent/conf.d/kubernetes_state_core.d/. The resolved mode is part of the default-config checksum, so toggling the field changes the cluster-agent pod-template annotation and forces a rollout instead of leaving the in-memory ConfigMap stale. Version gate: when either the cluster-side component (cluster-checks-runner if enabled, otherwise cluster-agent) OR the node-agent override image is parseable AND below 7.60, the operator skips the feature with a warning log rather than mounting an unsupported file into an older node-agent. Unparseable tags (:dev, :latest, custom registries) are assumed compatible. When podCollectionMode=node_kubelet is set alongside features.kubeStateMetricsCore.conf, the operator still deploys the node-side check but logs a descriptive warning pointing the user at the two valid ways to avoid double pod collection (omit pods from collectors, or set pod_collection_mode: cluster_unassigned themselves). Default behavior is byte-identical to today when the field is unset.
- Clarify PodCollectionMode godoc to disambiguate snake_case agent check options (pod_collection_mode in the rendered YAML) from the camelCase CRD field name (podCollectionMode). - Replace manual if/t.Fatalf checks in Test_ksmFeature_buildKSMCorePodsOnNodeConfigMap with require.True / require.NoError for consistency with the rest of the package's test style. - Use deep-equality on the parsed YAML in that test so future accidental additions to the generated node-side ConfigMap (e.g. an unwanted cluster_check field) fail the test rather than silently passing.
The previous godoc said cluster-wide aggregation metrics become "sliced per
host" and could be recovered with `sum by (kube_cluster_name)`. That is wrong
for the `.total` family (kubernetes_state.{container,initcontainer}.<res>_
{requested,limit}.total): those are emitted with a reduced tag set carrying no
host/node, so multiple node agents emit identical series that collide at
ingestion (last-write-wins) and under-report — unrecoverable at query time.
Host-tagged metrics like kubernetes_state.pod.count are unaffected.
Regenerated openapi, CRDs, and docs.
justin-lesko
force-pushed
the
minyi/ksm-pod-collection-on-node
branch
from
August 24, 2026 18:33
c2b6cd3 to
98aaa4d
Compare
Mathew-Estafanous
approved these changes
Aug 26, 2026
Mathew-Estafanous
left a comment
Contributor
There was a problem hiding this comment.
A couple small nits but everything else looks good.
gh-worker-dd-mergequeue-cf854d
Bot
deleted the
minyi/ksm-pod-collection-on-node
branch
August 28, 2026 15:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds
features.kubeStateMetricsCore.podCollectionModeoptions aredefaultandnode_kubeleton thev2alpha1
DatadogAgentCRD.When set to
node_kubelet, the operator:conf) by:pod_collection_mode: cluster_unassignedandcluster_aggregates_enabled: trueon the primary instance so it collects unscheduled pods while suppressing cluster-aggregate metrics.pod_collection_mode: cluster_aggregates_onlyto collect those aggregate metrics centrally.pod_collection_mode: node_kubelet,cluster_aggregates_enabled: true, andcollectors: [pods].When a user supplies
features.kubeStateMetricsCore.conf, the operator still creates the node-side check but does not modify the user-owned cluster-side YAML. The user must configure bothcluster_unassignedandcluster_aggregates_onlycluster-side instances themselves.This is equivalent to the following manual configuration:
Result: scheduled-pod metrics are emitted by each node agent locally from the Kubelet (no API-server traffic for pods). Unscheduled pods and every other KSM resource continue to be collected by the primary cluster-side instance, while cluster-aggregate metrics are collected by the dedicated
cluster_aggregates_onlyinstance. Default behavior is semantically unchanged when the field is unset.Motivation
In large clusters, pod metrics dominate the cardinality of the monolithic
kubernetes_state_corecluster check, making it the scaling bottleneck. The agent has supported offloading pod collection to
node-agents via
pod_collection_mode: node_kubeletsince 7.58, but customers had to assemble twocoordinated configs manually (
features.kubeStateMetricsCore.conf.configDatafor the cluster side,override.nodeAgent.extraConfdfor the node side) and carefully avoid double-collection or losingunscheduled-pod metrics as well as live without
.totalaggregate metrics. This field collapses that into a single typed toggle.Describe your test plan
Unit tests added in this PR:
TestKsmCheckConfigPodCollectionOnNodecluster_unassignedinstance with the full collector list andcluster_aggregates_enabled: true.cluster_aggregates_onlyinstance without a collector list orcluster_aggregates_enabled.pod_collection_modeis emitted.Test_ksmFeature_buildKSMCorePodsOnNodeConfigMapcluster_checkorskip_leader_electionfields.pod_collection_mode: node_kubeletcluster_aggregates_enabled: truecollectors: [pods]Manual end-to-end validation
Minimum Agent Versions