Skip to content

Commit 4ca5d19

Browse files
committed
MON-4115: expose label metrics for jobs and cronjobs
Adds `AdditionalLabelsAllowList` to KSM config. Signed-off-by: Pranshu Srivastava <[email protected]>
1 parent e7abc6a commit 4ca5d19

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

Documentation/api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ The `KubeStateMetricsConfig` resource defines settings for the `kube-state-metri
174174
| resources | *[v1.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#resourcerequirements-v1-core) | Defines resource requests and limits for the KubeStateMetrics container. |
175175
| tolerations | [][v1.Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#toleration-v1-core) | Defines tolerations for the pods. |
176176
| topologySpreadConstraints | []v1.TopologySpreadConstraint | Defines a pod's topology spread constraints. |
177+
| additionalLabelsAllowList | *string | Defines label-metrics' allow list for resources in addition to the default one. Currently, this is only supported for `jobs` and `cronjobs`, due to cardinality concerns. Refer: https://pkg.go.dev/k8s.io/kube-state-metrics/[email protected]/pkg/options#LabelsAllowList |
177178

178179
[Back to TOC](#table-of-contents)
179180

Documentation/openshiftdocs/modules/kubestatemetricsconfig.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Appears in: link:clustermonitoringconfiguration.adoc[ClusterMonitoringConfigurat
2626

2727
|topologySpreadConstraints|[]v1.TopologySpreadConstraint|Defines a pod's topology spread constraints.
2828

29+
|additionalLabelsAllowList|*string|Defines label-metrics' allow list for resources in addition to the default one. Currently, this is only supported for `jobs` and `cronjobs`, due to cardinality concerns. Refer: https://pkg.go.dev/k8s.io/kube-state-metrics/[email protected]/pkg/options#LabelsAllowList
30+
2931
|===
3032

3133
link:../index.adoc[Back to TOC]

pkg/manifests/manifests.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import (
4848
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4949
"k8s.io/apimachinery/pkg/util/sets"
5050
auditv1 "k8s.io/apiserver/pkg/apis/audit/v1"
51+
"k8s.io/klog/v2"
5152
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
5253
"k8s.io/utils/ptr"
5354
k8syaml "sigs.k8s.io/yaml"
@@ -760,6 +761,25 @@ func (f *Factory) KubeStateMetricsDeployment() (*appsv1.Deployment, error) {
760761
if f.config.ClusterMonitoringConfiguration.KubeStateMetricsConfig.Resources != nil {
761762
d.Spec.Template.Spec.Containers[i].Resources = *f.config.ClusterMonitoringConfiguration.KubeStateMetricsConfig.Resources
762763
}
764+
additionalAllowList := f.config.ClusterMonitoringConfiguration.KubeStateMetricsConfig.AdditionalLabelsAllowList
765+
if additionalAllowList != nil && *additionalAllowList != "" {
766+
err = validateLabelsAllowListFormat(*additionalAllowList)
767+
if err != nil {
768+
return nil, fmt.Errorf("error parsing allowlist: %w", err)
769+
}
770+
for i = range container.Args {
771+
if strings.HasPrefix(container.Args[i], "--metric-labels-allowlist=") {
772+
allowedResources := sets.New[string]("jobs", "cronjobs")
773+
gotResources := sets.New[string](strings.Split(*additionalAllowList, ",")...)
774+
acceptedResources := gotResources.Intersection(allowedResources).UnsortedList()
775+
rejectedResources := gotResources.Difference(allowedResources).UnsortedList()
776+
if len(rejectedResources) > 0 {
777+
klog.InfoS("ignoring unsupported resources in additionalLabelsAllowList", "rejectedResources", rejectedResources)
778+
}
779+
container.Args[i] += "," + strings.Join(acceptedResources, ",")
780+
}
781+
}
782+
}
763783
}
764784
}
765785

@@ -3614,3 +3634,65 @@ func hashStringMap(m map[string]string) string {
36143634
}
36153635
return hashByteMap(byteMap)
36163636
}
3637+
3638+
func validateLabelsAllowListFormat(value string) error {
3639+
var errLabelsAllowListFormat = errors.New("invalid format, should be: metric1=[label1,label2,labeln...],...,metricN=[...]")
3640+
3641+
// Taken from text/scanner EOF constant.
3642+
const EOF = -1
3643+
var (
3644+
m = map[string][]string{}
3645+
previous rune
3646+
next rune
3647+
firstWordPos int
3648+
name string
3649+
)
3650+
firstWordPos = 0
3651+
3652+
for i, v := range value {
3653+
if i+1 == len(value) {
3654+
next = EOF
3655+
} else {
3656+
next = []rune(value)[i+1]
3657+
}
3658+
if i-1 >= 0 {
3659+
previous = []rune(value)[i-1]
3660+
} else {
3661+
previous = v
3662+
}
3663+
3664+
switch v {
3665+
case '=':
3666+
if previous == ',' || next != '[' {
3667+
return errLabelsAllowListFormat
3668+
}
3669+
name = strings.TrimSpace(string([]rune(value)[firstWordPos:i]))
3670+
m[name] = []string{}
3671+
firstWordPos = i + 1
3672+
case '[':
3673+
if previous != '=' {
3674+
return errLabelsAllowListFormat
3675+
}
3676+
firstWordPos = i + 1
3677+
case ']':
3678+
// if after metric group, has char not comma or end.
3679+
if next != EOF && next != ',' {
3680+
return errLabelsAllowListFormat
3681+
}
3682+
if previous != '[' {
3683+
m[name] = append(m[name], strings.TrimSpace(string(([]rune(value)[firstWordPos:i]))))
3684+
}
3685+
firstWordPos = i + 1
3686+
case ',':
3687+
// if starts or ends with comma
3688+
if previous == v || next == EOF || next == ']' {
3689+
return errLabelsAllowListFormat
3690+
}
3691+
if previous != ']' {
3692+
m[name] = append(m[name], strings.TrimSpace(string(([]rune(value)[firstWordPos:i]))))
3693+
}
3694+
firstWordPos = i + 1
3695+
}
3696+
}
3697+
return nil
3698+
}

pkg/manifests/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ type KubeStateMetricsConfig struct {
175175
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
176176
// Defines a pod's topology spread constraints.
177177
TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
178+
// Defines label-metrics' allow list for resources in addition to the default one.
179+
// Currently, this is only supported for `jobs` and `cronjobs`, due to cardinality concerns.
180+
// Refer: https://pkg.go.dev/k8s.io/kube-state-metrics/[email protected]/pkg/options#LabelsAllowList
181+
AdditionalLabelsAllowList *string `json:"additionalLabelsAllowList,omitempty"`
178182
}
179183

180184
// The `PrometheusK8sConfig` resource defines settings for the Prometheus

0 commit comments

Comments
 (0)