pkg/kubelet: add kubelet_metrics_provider metric

This metric is meant to help end-users identify which metrics provider
kubelet is using under the hood to expose container stats.

Signed-off-by: Damien Grisonnet <dgrisonn@redhat.com>
This commit is contained in:
Damien Grisonnet
2026-02-11 20:24:37 +01:00
parent 8b09f925a7
commit 22706b7bdf
3 changed files with 88 additions and 0 deletions

View File

@@ -26,6 +26,9 @@ import (
const (
kubeletSubsystem = "kubelet"
CAdvisorMetricsProvider MetricsProviderType = "cadvisor"
CRIMetricsProvider MetricsProviderType = "cri"
)
var (
@@ -76,6 +79,15 @@ var (
},
[]string{"metric_source"},
)
MetricsProvider = metrics.NewGaugeVec(
&metrics.GaugeOpts{
Subsystem: kubeletSubsystem,
Name: "metrics_provider",
Help: "Metrics provider used by kubelet to collect container stats. Values can be 'cadvisor' and 'cri'",
StabilityLevel: metrics.ALPHA,
},
[]string{"provider"},
)
)
var registerMetrics sync.Once
@@ -87,6 +99,7 @@ func Register() {
legacyregistry.MustRegister(HTTPRequestsDuration)
legacyregistry.MustRegister(HTTPInflightRequests)
legacyregistry.MustRegister(VolumeStatCalDuration)
legacyregistry.MustRegister(MetricsProvider)
})
}
@@ -99,3 +112,11 @@ func SinceInSeconds(start time.Time) float64 {
func CollectVolumeStatCalDuration(metricSource string, start time.Time) {
VolumeStatCalDuration.WithLabelValues(metricSource).Observe(SinceInSeconds(start))
}
type MetricsProviderType string
// SetMetricsProvider sets the metrics provider.
func SetMetricsProvider(provider MetricsProviderType) {
MetricsProvider.Reset()
MetricsProvider.WithLabelValues(string(provider)).Set(1)
}

View File

@@ -0,0 +1,65 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"strings"
"testing"
"k8s.io/component-base/metrics/legacyregistry"
"k8s.io/component-base/metrics/testutil"
)
func TestSetMetricsProvider(t *testing.T) {
Register()
MetricsProvider.Reset()
tests := []struct {
name string
provider MetricsProviderType
want string
}{
{
name: "cadvisor provider",
provider: CAdvisorMetricsProvider,
want: `
# HELP kubelet_metrics_provider [ALPHA] Metrics provider used by kubelet to collect container stats. Values can be 'cadvisor' and 'cri'
# TYPE kubelet_metrics_provider gauge
kubelet_metrics_provider{provider="cadvisor"} 1
`,
},
{
name: "cri provider",
provider: CRIMetricsProvider,
want: `
# HELP kubelet_metrics_provider [ALPHA] Metrics provider used by kubelet to collect container stats. Values can be 'cadvisor' and 'cri'
# TYPE kubelet_metrics_provider gauge
kubelet_metrics_provider{provider="cri"} 1
`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
SetMetricsProvider(tt.provider)
if err := testutil.GatherAndCompare(legacyregistry.DefaultGatherer, strings.NewReader(tt.want), "kubelet_metrics_provider"); err != nil {
t.Errorf("unexpected metric output: %v", err)
}
})
}
}

View File

@@ -476,6 +476,7 @@ func (s *Server) InstallAuthNotRequiredHandlers(ctx context.Context) {
r.RawMustRegister(metrics.NewPrometheusMachineCollector(prometheusHostAdapter{s.host}, includedMetrics))
if utilfeature.DefaultFeatureGate.Enabled(features.PodAndContainerStatsFromCRI) {
r.CustomRegister(collectors.NewCRIMetricsCollector(context.TODO(), s.host.ListPodSandboxMetrics, s.host.ListMetricDescriptors))
servermetrics.SetMetricsProvider(servermetrics.CRIMetricsProvider)
} else {
cadvisorOpts := cadvisorv2.RequestOptions{
IdType: cadvisorv2.TypeName,
@@ -483,6 +484,7 @@ func (s *Server) InstallAuthNotRequiredHandlers(ctx context.Context) {
Recursive: true,
}
r.RawMustRegister(metrics.NewPrometheusCollector(prometheusHostAdapter{s.host}, containerPrometheusLabelsFunc(s.host), includedMetrics, clock.RealClock{}, cadvisorOpts))
servermetrics.SetMetricsProvider(servermetrics.CAdvisorMetricsProvider)
}
s.restfulCont.Handle(cadvisorMetricsPath,
compbasemetrics.HandlerFor(r, compbasemetrics.HandlerOpts{ErrorHandling: compbasemetrics.ContinueOnError}),