From 56cd8b2fc61569cd937431fea0416b86789b598b Mon Sep 17 00:00:00 2001 From: Richa Banker Date: Mon, 16 Mar 2026 11:58:12 -0700 Subject: [PATCH] Enable native histograms gated by feature flag in kubelet Signed-off-by: Richa Banker --- cmd/kubelet/app/server.go | 4 ++++ pkg/kubelet/server/server_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index aef191f07df..f58fcba1bb8 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -83,6 +83,7 @@ import ( "k8s.io/component-base/logs" logsapi "k8s.io/component-base/logs/api/v1" "k8s.io/component-base/metrics" + metricsfeatures "k8s.io/component-base/metrics/features" "k8s.io/component-base/metrics/legacyregistry" "k8s.io/component-base/tracing" "k8s.io/component-base/version" @@ -633,6 +634,9 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend if err != nil { return err } + // Propagate feature gate state to the metrics subsystem. This must be called + // after feature gates are set and before any histogram metrics are registered. + metricsfeatures.ApplyFeatureGates(featureGate) // validate the initial KubeletServer (we set feature gates first, because this validation depends on feature gates) if err := options.ValidateKubeletServer(s); err != nil { return err diff --git a/pkg/kubelet/server/server_test.go b/pkg/kubelet/server/server_test.go index 6c268c6244e..1875897f01b 100644 --- a/pkg/kubelet/server/server_test.go +++ b/pkg/kubelet/server/server_test.go @@ -72,6 +72,7 @@ import ( "k8s.io/apiserver/pkg/server/healthz" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" + metricsfeatures "k8s.io/component-base/metrics/features" "k8s.io/component-base/metrics/legacyregistry" "k8s.io/component-base/metrics/testutil" zpagesfeatures "k8s.io/component-base/zpages/features" @@ -82,6 +83,7 @@ import ( "k8s.io/kubernetes/pkg/features" kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/config" "k8s.io/kubernetes/pkg/kubelet/cm" + kubeletmetrics "k8s.io/kubernetes/pkg/kubelet/metrics" servermetrics "k8s.io/kubernetes/pkg/kubelet/server/metrics" "k8s.io/kubernetes/pkg/kubelet/server/stats" "k8s.io/kubernetes/pkg/volume" @@ -2483,3 +2485,26 @@ kubelet_websocket_streaming_requests_total{subresource="portforward"} 1 }) } } + +func TestKubeletNativeHistogramMetrics(t *testing.T) { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, metricsfeatures.NativeHistograms, true) + metricsfeatures.ApplyFeatureGates(utilfeature.DefaultFeatureGate) + kubeletmetrics.Register() + + tCtx := ktesting.Init(t) + fw := newServerTest(tCtx) + defer fw.testHTTPServer.Close() + + histogramMetric := "kubelet_pod_start_duration_seconds" + metrics, err := testutil.ScrapeMetricsProto(fw.testHTTPServer.URL+"/metrics", fw.testHTTPServer.Client()) + if err != nil { + t.Fatalf("failed to scrape metrics: %v", err) + } + + mf, ok := metrics[histogramMetric] + if !ok { + t.Fatalf("metric %q not found in kubelet metrics endpoint", histogramMetric) + } + + testutil.AssertHasNativeHistogram(t, mf, nil) +}