-
Notifications
You must be signed in to change notification settings - Fork 408
feat: add configurable additional labels to NodePool metrics #2685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add configurable additional labels to NodePool metrics #2685
Conversation
|
Hi @moko-poi. Thanks for your PR. I'm waiting for a github.com member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. 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. |
16e9f2b to
f0f968e
Compare
|
The test is failing, but we've addressed it in #2687 (comment) . |
| if value, ok := nodePool.Labels[labelKey]; ok { | ||
| labels[labelKey] = value | ||
| } else { | ||
| labels[labelKey] = "" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already produces empty string on missing
| if value, ok := nodePool.Labels[labelKey]; ok { | |
| labels[labelKey] = value | |
| } else { | |
| labels[labelKey] = "" | |
| } | |
| labels[labelKey] = nodePool.Labels[labelKey] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Fixed in bbe404f
| nodePool.Labels = map[string]string{ | ||
| "capacity_type": "spot", | ||
| "zone": "us-east-1a", | ||
| "architecture": "amd64", | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do these labels even commonly exist ?
I was hoping zone would translate to topology.kubernetes.io/zone
... maybe have that as the only default since it is a well known label ?
(alternatively have no defaults so this is noop for users that don't care)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@grosser f461d94
I've removed the default values entirely. The default is now an empty string, making this a no-op unless users explicitly configure it. This keeps the PR focused on providing the capability for users to configure additional metric labels, without making assumptions about which labels exist on their NodePools.
pkg/operator/options/options.go
Outdated
| if o.rawAdditionalNodePoolMetricLabels != "" { | ||
| o.AdditionalNodePoolMetricLabels = lo.Map(strings.Split(o.rawAdditionalNodePoolMetricLabels, ","), func(s string, _ int) string { | ||
| return strings.TrimSpace(s) | ||
| }) | ||
| } else { | ||
| o.AdditionalNodePoolMetricLabels = []string{} | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: less code paths 🤷
| if o.rawAdditionalNodePoolMetricLabels != "" { | |
| o.AdditionalNodePoolMetricLabels = lo.Map(strings.Split(o.rawAdditionalNodePoolMetricLabels, ","), func(s string, _ int) string { | |
| return strings.TrimSpace(s) | |
| }) | |
| } else { | |
| o.AdditionalNodePoolMetricLabels = []string{} | |
| } | |
| o.AdditionalNodePoolMetricLabels = lo.Map(strings.Split(o.rawAdditionalNodePoolMetricLabels, ","), func(s string, _ int) string { | |
| return strings.TrimSpace(s) | |
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3377cac
Updated to use lo.FilterMap to reduce code paths as suggested. I also added filtering for empty strings since strings.Split("", ",") returns []string{""} rather than an empty slice, which would cause invalid empty label keys in the metrics controller.
grosser
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic makes sense
idk about the defaults
1595f79 to
f461d94
Compare
|
@grosser This keeps the PR scope focused on providing the capability for users to add custom labels to their metrics, rather than imposing specific defaults that may not match their label schemas. |
Pull Request Test Coverage Report for Build 20636338260Details
💛 - Coveralls |
f461d94 to
48d503e
Compare
grosser
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✨
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: grosser, moko-poi 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 |
Replace conditional logic with lo.FilterMap to reduce code paths and filter empty strings. This prevents invalid empty label keys from being added to metrics when the input contains empty strings or consecutive commas.
48d503e to
c9213b0
Compare
What problem does this PR solve?
Closes #2221
Allows users to customize which NodePool labels are included in NodePool metrics (
karpenter_nodepools_limitandkarpenter_nodepools_usage), enabling better observability for custom attributes like capacity type, availability zone, and architecture.How does this PR solve the problem?
Implementation approach
Added a CLI flag
--additional-nodepool-metric-labels(environment variable:ADDITIONAL_NODEPOOL_METRIC_LABELS) that accepts a comma-separated list of label keys to include in NodePool metrics.Default behavior: No additional labels (empty by default). Users must explicitly configure which labels to include.
Key design decisions
CLI flag instead of annotations: Satisfies Prometheus constraint that all time series for a metric must have identical label keys. Label keys are fixed at startup when metrics are registered.
Deferred initialization: Follows the same pattern as Node metrics controller - metrics are declared as package variables but initialized in
initializeMetrics()called fromNewController(). This ensures options are available when building the label key set.Empty string for missing labels: If a NodePool doesn't have a specified label, the metric uses an empty string
""for that label value. This maintains consistent label keys across all NodePools while allowing flexibility.No defaults: By not providing default labels, this PR stays focused on providing the capability without making assumptions about which labels exist on users' NodePools.
Example usage
With a NodePool:
When configured with --additional-nodepool-metric-labels=capacity_type,zone,architecture, produces metrics:
Without the flag, produces metrics:
Testing
Checklist