From 235b2e290566aa7b3bb6271cc9e4cb78a485f90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9na=C3=AFc=20Huard?= Date: Tue, 5 Nov 2024 11:55:51 +0100 Subject: [PATCH] Fix node kubelet collector mode for KSM pod metrics collection --- .../cluster/ksm/customresources/pod.go | 11 +++++--- pkg/kubestatemetrics/builder/builder.go | 26 ++++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/pkg/collector/corechecks/cluster/ksm/customresources/pod.go b/pkg/collector/corechecks/cluster/ksm/customresources/pod.go index 5b700efca9827b..b85b437e72379f 100644 --- a/pkg/collector/corechecks/cluster/ksm/customresources/pod.go +++ b/pkg/collector/corechecks/cluster/ksm/customresources/pod.go @@ -220,10 +220,13 @@ func (f *extendedPodFactory) customResourceGenerator(p *v1.Pod, resourceType str func wrapPodFunc(f func(*v1.Pod) *metric.Family) func(interface{}) *metric.Family { return func(obj interface{}) *metric.Family { - pod := &v1.Pod{} - if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.(*unstructured.Unstructured).Object, pod); err != nil { - log.Warnf("cannot decode object %q into v1.Pod, err=%s, skipping", obj.(*unstructured.Unstructured).Object["apiVersion"], err) - return nil + var pod *v1.Pod + var ok bool + if pod, ok = obj.(*v1.Pod); !ok { + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.(*unstructured.Unstructured).Object, pod); err != nil { + log.Warnf("cannot decode object %q into v1.Pod, err=%s, skipping", obj.(*unstructured.Unstructured).Object["apiVersion"], err) + return nil + } } metricFamily := f(pod) diff --git a/pkg/kubestatemetrics/builder/builder.go b/pkg/kubestatemetrics/builder/builder.go index 93074c0e568a9f..d0c5ebd1ea9984 100644 --- a/pkg/kubestatemetrics/builder/builder.go +++ b/pkg/kubestatemetrics/builder/builder.go @@ -16,6 +16,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" @@ -190,15 +191,21 @@ func GenerateStores[T any]( filteredMetricFamilies := generator.FilterFamilyGenerators(b.allowDenyList, metricFamilies) composedMetricGenFuncs := generator.ComposeMetricGenFuncs(filteredMetricFamilies) + isPod := false + if _, ok := expectedType.(*corev1.Pod); ok { + isPod = true + } else if u, ok := expectedType.(*unstructured.Unstructured); ok { + isPod = u.GetAPIVersion() == "v1" && u.GetKind() == "Pod" + } + if b.namespaces.IsAllNamespaces() { store := store.NewMetricsStore(composedMetricGenFuncs, reflect.TypeOf(expectedType).String()) - switch expectedType.(type) { - // Pods are handled differently because depending on the configuration - // they're collected from the API server or the Kubelet. - case *corev1.Pod: + if isPod { + // Pods are handled differently because depending on the configuration + // they're collected from the API server or the Kubelet. handlePodCollection(b, store, client, listWatchFunc, corev1.NamespaceAll, useAPIServerCache) - default: + } else { listWatcher := listWatchFunc(client, corev1.NamespaceAll, b.fieldSelectorFilter) b.startReflector(expectedType, store, listWatcher, useAPIServerCache) } @@ -209,12 +216,11 @@ func GenerateStores[T any]( stores := make([]cache.Store, 0, len(b.namespaces)) for _, ns := range b.namespaces { store := store.NewMetricsStore(composedMetricGenFuncs, reflect.TypeOf(expectedType).String()) - switch expectedType.(type) { - // Pods are handled differently because depending on the configuration - // they're collected from the API server or the Kubelet. - case *corev1.Pod: + if isPod { + // Pods are handled differently because depending on the configuration + // they're collected from the API server or the Kubelet. handlePodCollection(b, store, client, listWatchFunc, ns, useAPIServerCache) - default: + } else { listWatcher := listWatchFunc(client, ns, b.fieldSelectorFilter) b.startReflector(expectedType, store, listWatcher, useAPIServerCache) }