Repository navigation
feat: filter out Karpenter node labels from container insights metrics - #2310
Closed
petruanica wants to merge 2 commits into
Closed
petruanica wants to merge 2 commits into
petruanica wants to merge 2 commits into
Conversation
Collaborator
|
Call out a bit more that this is breaking and has to be part of major version bump. Just highlight it more in description |
louisall
reviewed
Oct 1, 2026
…t.type
BREAKING CHANGE: removes 25 node-label dimensions from every Container
Insights metric emitted from a Karpenter-managed node. Any dashboard, alarm
or query selecting on one of them stops matching. There is no deprecation
window and no opt-out, so this belongs in a major version bump.
Karpenter applies its well-known labels to every node it manages, and the
Kubernetes attribute enrichment in the Container Insights pipelines copies
them onto the resource block, so their key text is attached to every
datapoint of every series emitted from such a node, across all receivers.
Most are derived from instance type details, so they restate host.type,
which these pipelines already publish.
The awsattributelimit/cw_k8s_ci_v0 denylist already removes comparable
platform-injected label families (feature.node.kubernetes.io/,
beta.kubernetes.io/, alpha.eksctl.io/, sourceLaunchTemplateId). The
Karpenter equivalents were never added.
Adds 25 keys to unconditional_removal_keys across the 12 Container Insights
pipeline configs that carry the processor and the 7 golden sample configs
that contain it: 22 karpenter.k8s.aws/instance-* and 3 karpenter.sh/
reconciliation-state labels. The two filelog_* pipelines have no
attribute-limit processor and are unchanged. These labels appear only as
resource attributes, so unconditional_removal_keys, which is
resource-scoped, is sufficient; no datapoint-level delete_key is needed.
The list is now complete against upstream's WellKnownLabels. Karpenter
defines 28 labels in the karpenter.k8s.aws/ domain and 5 in karpenter.sh/;
this denies 22 and 3, retaining the remaining 8 deliberately:
- karpenter.sh/nodepool, karpenter.sh/capacity-type and
karpenter.k8s.aws/ec2nodeclass carry provisioning identity, with
capacity-type the only signal distinguishing spot from on-demand.
- capacity-reservation-{id,type,interruptible} record which capacity
reservation a node consumed, whether it is an ordinary On-Demand
Capacity Reservation or a Capacity Block, and whether EC2 may reclaim
it. Not derivable from the instance type.
- placement-group-{id,partition} record which EC2 placement group the
instance launched into and, for partition placement groups, which
partition. A partition is an independent failure domain, so this is a
physical fault boundary rather than an instance property.
That is why the change lists exact keys rather than adding the
karpenter.k8s.aws/ and karpenter.sh/ prefixes to
unconditional_removal_prefixes, which would strip all 8 retained keys too.
The four instance-gpu-* and three instance-accelerator-* keys are included.
Karpenter sets them conditionally — computeRequirements populates the GPU
labels only when the instance type reports GPU info, and the accelerator
labels only for Inferentia or Neuron devices — so they are absent from
clusters with no accelerated nodes. They are the same class as instance-cpu
and instance-memory. GPU and Neuron dashboards are unaffected, because
device identity travels on the DCGM_FI_DEV_* and neuroncore_* metrics' own
datapoint attributes, which this does not touch. Note that the Neuron
branch also populates the accelerator labels, so this covers Trainium and
Inferentia2 as well as Inferentia1.
Golden sample configs updated. Additive only, 25 lines per file, no Go
changes.
petruanica
force-pushed
the
otel-ci-drop-karpenter-labels
branch
from
October 5, 2026 13:24
11c519c to
c9e25bb
Compare
This was referenced Oct 7, 2026
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.
Important
This is a breaking change and must ship in a major version bump. It removes 25 node-label dimensions from every Container Insights metric emitted from a Karpenter-managed node. Any dashboard, alarm, or query that selects or groups on one of them stops matching the moment the new config rolls out. There is no deprecation window and no per-customer opt-out in this change: the attributes are dropped at the processor, so they disappear in a single release. The chart counterpart therefore needs a major chart version bump (
6.xto7.0.0), and neither change should be picked into a minor or patch release.Note
Release coordination (working assumption, not yet decided). This PR is written assuming it ships together with the two sibling Container Insights changes in a single major chart release,
v7.0.0. That bundling has not been agreed yet — it is recorded here so reviewers know what the description assumes, and it needs confirming before any of the three merge. If they end up shipping separately, each breaking change still needs its own major bump.Description of the issue
Karpenter applies its well-known labels to every node it manages, and the Kubernetes attribute enrichment in the OTel Container Insights pipelines copies them onto the resource block — so their key text is attached to every datapoint of every series emitted from a Karpenter-managed node, across all receivers. Most of them are derived from instance type details, so they restate
host.type, which these pipelines already publish.The
awsattributelimit/cw_k8s_ci_v0denylist already removes comparable platform-injected label families (feature.node.kubernetes.io/,beta.kubernetes.io/,alpha.eksctl.io/,sourceLaunchTemplateId). The Karpenter equivalents were never added.Description of changes
Adds 25 Karpenter node-label keys to
awsattributelimit/cw_k8s_ci_v0.unconditional_removal_keys— 22karpenter.k8s.aws/instance-*and 3karpenter.sh/lifecycle labels — across the 12 Container Insights pipeline configs that carry the processor and the 7translator/tocwconfig/sampleConfig/opentelemetry/golden files that contain it. The twofilelog_*pipelines have no attribute-limit processor and are unchanged. Additive only, 25 lines per file, no Go changes.These labels appear only as resource attributes, so
unconditional_removal_keys— which is resource-scoped — is sufficient; no datapoint-leveldelete_keytransform is needed.What is removed and what is kept
The list is now complete against upstream's
WellKnownLabels. Karpenter defines 28 labels in thekarpenter.k8s.aws/domain and 5 inkarpenter.sh/; this denies 22 and 3 of them respectively, and retains the remaining 8 deliberately.Retained, because they are not instance properties and are legitimate grouping dimensions:
karpenter.sh/nodepool,karpenter.k8s.aws/ec2nodeclass,karpenter.sh/capacity-type— provisioning identity, withcapacity-typethe only signal distinguishing spot from on-demand capacity.karpenter.k8s.aws/capacity-reservation-id,-type,-interruptible— which capacity reservation a node consumed, whether it is an ordinary On-Demand Capacity Reservation or a Capacity Block, and whether EC2 may reclaim it. Not derivable from the instance type.karpenter.k8s.aws/placement-group-id,-partition— which EC2 placement group the instance launched into, and for partition placement groups which partition. A partition is an independent failure domain, so this is a physical fault boundary rather than an instance property.That is also why the change lists exact keys rather than adding
karpenter.k8s.aws/andkarpenter.sh/tounconditional_removal_prefixes, which would strip all 8 retained keys as well.GPU and accelerator labels
The four
instance-gpu-*and threeinstance-accelerator-*keys were added after review feedback. Karpenter populates them conditionally —computeRequirementssets the GPU labels only when the instance type reports GPU info, and the accelerator labels only for Inferentia or Neuron devices — so they are absent from clusters with no accelerated nodes and were missed when the list was first assembled. They are the same class asinstance-cpuandinstance-memory: properties of the instance type that restatehost.type.GPU and Neuron dashboards are unaffected, because device identity travels on the
DCGM_FI_DEV_*andneuroncore_*metrics' own datapoint attributes, which this change does not touch. Note that the Neuron branch also populates the accelerator labels, so this covers Trainium and Inferentia2 as well as Inferentia1.Breaking change and release sequencing
Customers see the removed dimensions on two surfaces: the
k8s_node_label_karpenter_*metric label, and the@resource.prefix in PromQL. Both stop resolving for the 25 denied keys. Concretely, a query grouping bykarpenter.k8s.aws/instance-familyto compare utilisation across instance families returns a single unlabelled series afterwards, and an alarm scoped to a specificinstance-sizestops matching any series at all.Because the keys are listed in a static config with no conditional and no values-level toggle, a customer who relies on one of them has no way to retain it in the release that removes it. That is the reason this needs a major version bump rather than a minor, and it should be called out in the release notes alongside the chart counterpart.
License
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Tests
go test ./translator/tocwconfig/— the golden tests covering the edited sample configs pass (TestContainerInsightsConfig,TestContainerInsightsAKSGKEConfig,TestDefaultOtelConfigAKSTranslation,TestDefaultOtelConfigGKETranslation), rendering the pipeline templates and diffing them against the goldens.New integration coverage in aws/amazon-cloudwatch-agent-test#775. That PR also carries two tests for the pod-label counterpart keys, which this change does not implement; they assert behaviour introduced by the chart counterpart and will fail until the equivalent keys land here too. The two tests covering this change:
TestKarpenterInstanceLabelsRemovedasserts none of the 25 denied keys reach resource scope on any node-label-enriched metric, andTestKarpenterGroupingLabelsRetainedasserts the three retained keys still arrive. The pair is what makes the exact-keys decision testable — a regression replacing the 25 entries with thekarpenter.k8s.aws/andkarpenter.sh/prefixes would pass the first and fail the second. The retention test requires at least one node in the result set to carry ak8s.node.label.karpenter.*attribute, so a change that stripped every Karpenter attribute fails rather than skips.Both were validated on a live EKS cluster, since the claim is about what arrives in CloudWatch rather than what the config renders to. The changed configuration was applied to the running agent and cluster scraper, the pods were restarted, and metrics were given 30 minutes to settle;
test/otel/standard -computeType=EKSthen asserts on datapoints read back from CloudWatch. The suite was also run before the change, because an "attribute is absent" assertion passes trivially against empty data.TestKarpenterInstanceLabelsRemovedTestKarpenterGroupingLabelsRetained(guard)No failures, no skips. The guard passing both before and after shows only the intended keys were removed, and establishes that the result set genuinely contained Karpenter labels.
Requirements
Before commiting your code, please do the following steps.
make fmtandmake fmt-shmake lintRelated pull requests
Scope note: this change covers the Karpenter keys only; the chart counterpart additionally denies six pod-label counterpart keys, so the two are not yet identical.
PR Checklist
makepasses locally (build, unit tests, lint)Integration Tests
To run integration tests against this PR, add the
ready for testinglabel.