From eba5a49f10f40ef0b9ecfcee3c27949c6dd59728 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Fri, 16 Feb 2018 09:53:38 +0100 Subject: [PATCH] UPSTREAM: 59170: Fix kubelet PVC stale metrics --- vendor/k8s.io/kubernetes/pkg/kubelet/BUILD | 1 + .../k8s.io/kubernetes/pkg/kubelet/kubelet.go | 3 +- .../kubernetes/pkg/kubelet/metrics/BUILD | 5 +- .../pkg/kubelet/metrics/collectors/BUILD | 48 +++++ .../kubelet/metrics/collectors/helper_test.go | 182 ++++++++++++++++++ .../metrics/collectors/volume_stats.go | 120 ++++++++++++ .../metrics/collectors/volume_stats_test.go | 135 +++++++++++++ .../kubernetes/pkg/kubelet/metrics/metrics.go | 59 +----- .../kubernetes/pkg/kubelet/server/stats/BUILD | 1 - .../server/stats/volume_stat_calculator.go | 13 -- 10 files changed, 496 insertions(+), 71 deletions(-) create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/BUILD create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/helper_test.go create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/volume_stats.go create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/volume_stats_test.go diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/BUILD index 7fb535012420..ed4ff558b536 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/BUILD @@ -64,6 +64,7 @@ go_library( "//pkg/kubelet/kuberuntime:go_default_library", "//pkg/kubelet/lifecycle:go_default_library", "//pkg/kubelet/metrics:go_default_library", + "//pkg/kubelet/metrics/collectors:go_default_library", "//pkg/kubelet/mountpod:go_default_library", "//pkg/kubelet/network:go_default_library", "//pkg/kubelet/network/dns:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go index 0074fd816c92..56de1ebb0c91 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go @@ -75,6 +75,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/kuberuntime" "k8s.io/kubernetes/pkg/kubelet/lifecycle" "k8s.io/kubernetes/pkg/kubelet/metrics" + "k8s.io/kubernetes/pkg/kubelet/metrics/collectors" "k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/kubelet/network/dns" "k8s.io/kubernetes/pkg/kubelet/pleg" @@ -1291,7 +1292,7 @@ func (kl *Kubelet) StartGarbageCollection() { // Note that the modules here must not depend on modules that are not initialized here. func (kl *Kubelet) initializeModules() error { // Prometheus metrics. - metrics.Register(kl.runtimeCache) + metrics.Register(kl.runtimeCache, collectors.NewVolumeStatsCollector(kl)) // Setup filesystem directories. if err := kl.setupDataDirs(); err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/BUILD index 568ae707755c..2f8d8839738a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/BUILD @@ -25,6 +25,9 @@ filegroup( filegroup( name = "all-srcs", - srcs = [":package-srcs"], + srcs = [ + ":package-srcs", + "//pkg/kubelet/metrics/collectors:all-srcs", + ], tags = ["automanaged"], ) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/BUILD new file mode 100644 index 000000000000..66b6f240f1e6 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/BUILD @@ -0,0 +1,48 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["volume_stats.go"], + importpath = "k8s.io/kubernetes/pkg/kubelet/metrics/collectors", + visibility = ["//visibility:public"], + deps = [ + "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", + "//pkg/kubelet/metrics:go_default_library", + "//pkg/kubelet/server/stats:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = [ + "helper_test.go", + "volume_stats_test.go", + ], + embed = [":go_default_library"], + importpath = "k8s.io/kubernetes/pkg/kubelet/metrics/collectors", + deps = [ + "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", + "//pkg/kubelet/server/stats/testing:go_default_library", + "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", + "//vendor/github.com/prometheus/client_model/go:go_default_library", + "//vendor/github.com/prometheus/common/expfmt:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/helper_test.go b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/helper_test.go new file mode 100644 index 000000000000..a63f80b932f6 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/helper_test.go @@ -0,0 +1,182 @@ +/* +Copyright 2018 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. +*/ + +// testing helpers copied from k8s.io/kube-state-metrics/collectors/deployment_test.go +// TODO: share in a public package? + +package collectors + +import ( + "bytes" + "fmt" + "reflect" + "sort" + "strings" + + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" + "github.com/prometheus/common/expfmt" +) + +// gatherAndCompare retrieves all metrics exposed by a collector and compares it +// to an expected output in the Prometheus text exposition format. +// metricNames allows only comparing the given metrics. All are compared if it's nil. +func gatherAndCompare(c prometheus.Collector, expected string, metricNames []string) error { + expected = removeUnusedWhitespace(expected) + + reg := prometheus.NewPedanticRegistry() + if err := reg.Register(c); err != nil { + return fmt.Errorf("registering collector failed: %s", err) + } + metrics, err := reg.Gather() + if err != nil { + return fmt.Errorf("gathering metrics failed: %s", err) + } + if metricNames != nil { + metrics = filterMetrics(metrics, metricNames) + } + var tp expfmt.TextParser + expectedMetrics, err := tp.TextToMetricFamilies(bytes.NewReader([]byte(expected))) + if err != nil { + return fmt.Errorf("parsing expected metrics failed: %s", err) + } + + if !reflect.DeepEqual(metrics, normalizeMetricFamilies(expectedMetrics)) { + // Encode the gathered output to the readbale text format for comparison. + var buf1 bytes.Buffer + enc := expfmt.NewEncoder(&buf1, expfmt.FmtText) + for _, mf := range metrics { + if err := enc.Encode(mf); err != nil { + return fmt.Errorf("encoding result failed: %s", err) + } + } + // Encode normalized expected metrics again to generate them in the same ordering + // the registry does to spot differences more easily. + var buf2 bytes.Buffer + enc = expfmt.NewEncoder(&buf2, expfmt.FmtText) + for _, mf := range normalizeMetricFamilies(expectedMetrics) { + if err := enc.Encode(mf); err != nil { + return fmt.Errorf("encoding result failed: %s", err) + } + } + + return fmt.Errorf(`metric output does not match expectation; want: +%s + +got: + +%s`, buf2.String(), buf1.String()) + } + return nil +} + +func filterMetrics(metrics []*dto.MetricFamily, names []string) []*dto.MetricFamily { + var filtered []*dto.MetricFamily + for _, m := range metrics { + drop := true + for _, name := range names { + if m.GetName() == name { + drop = false + break + } + } + if !drop { + filtered = append(filtered, m) + } + } + return filtered +} + +func removeUnusedWhitespace(s string) string { + var ( + trimmedLine string + trimmedLines []string + lines = strings.Split(s, "\n") + ) + + for _, l := range lines { + trimmedLine = strings.TrimSpace(l) + + if len(trimmedLine) > 0 { + trimmedLines = append(trimmedLines, trimmedLine) + } + } + + // The Prometheus metrics representation parser expects an empty line at the + // end otherwise fails with an unexpected EOF error. + return strings.Join(trimmedLines, "\n") + "\n" +} + +// The below sorting code is copied form the Prometheus client library modulo the added +// label pair sorting. +// https://github.com/prometheus/client_golang/blob/ea6e1db4cb8127eeb0b6954f7320363e5451820f/prometheus/registry.go#L642-L684 + +// metricSorter is a sortable slice of *dto.Metric. +type metricSorter []*dto.Metric + +func (s metricSorter) Len() int { + return len(s) +} + +func (s metricSorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s metricSorter) Less(i, j int) bool { + sort.Sort(prometheus.LabelPairSorter(s[i].Label)) + sort.Sort(prometheus.LabelPairSorter(s[j].Label)) + + if len(s[i].Label) != len(s[j].Label) { + return len(s[i].Label) < len(s[j].Label) + } + + for n, lp := range s[i].Label { + vi := lp.GetValue() + vj := s[j].Label[n].GetValue() + if vi != vj { + return vi < vj + } + } + + if s[i].TimestampMs == nil { + return false + } + if s[j].TimestampMs == nil { + return true + } + return s[i].GetTimestampMs() < s[j].GetTimestampMs() +} + +// normalizeMetricFamilies returns a MetricFamily slice with empty +// MetricFamilies pruned and the remaining MetricFamilies sorted by name within +// the slice, with the contained Metrics sorted within each MetricFamily. +func normalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily { + for _, mf := range metricFamiliesByName { + sort.Sort(metricSorter(mf.Metric)) + } + names := make([]string, 0, len(metricFamiliesByName)) + for name, mf := range metricFamiliesByName { + if len(mf.Metric) > 0 { + names = append(names, name) + } + } + sort.Strings(names) + result := make([]*dto.MetricFamily, 0, len(names)) + for _, name := range names { + result = append(result, metricFamiliesByName[name]) + } + return result +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/volume_stats.go b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/volume_stats.go new file mode 100644 index 000000000000..7f80243dc975 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/volume_stats.go @@ -0,0 +1,120 @@ +/* +Copyright 2018 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 collectors + +import ( + "github.com/golang/glog" + "github.com/prometheus/client_golang/prometheus" + "k8s.io/apimachinery/pkg/util/sets" + stats "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1" + "k8s.io/kubernetes/pkg/kubelet/metrics" + serverstats "k8s.io/kubernetes/pkg/kubelet/server/stats" +) + +var ( + volumeStatsCapacityBytesDesc = prometheus.NewDesc( + prometheus.BuildFQName("", metrics.KubeletSubsystem, metrics.VolumeStatsCapacityBytesKey), + "Capacity in bytes of the volume", + []string{"namespace", "persistentvolumeclaim"}, nil, + ) + volumeStatsAvailableBytesDesc = prometheus.NewDesc( + prometheus.BuildFQName("", metrics.KubeletSubsystem, metrics.VolumeStatsAvailableBytesKey), + "Number of available bytes in the volume", + []string{"namespace", "persistentvolumeclaim"}, nil, + ) + volumeStatsUsedBytesDesc = prometheus.NewDesc( + prometheus.BuildFQName("", metrics.KubeletSubsystem, metrics.VolumeStatsUsedBytesKey), + "Number of used bytes in the volume", + []string{"namespace", "persistentvolumeclaim"}, nil, + ) + volumeStatsInodesDesc = prometheus.NewDesc( + prometheus.BuildFQName("", metrics.KubeletSubsystem, metrics.VolumeStatsInodesKey), + "Maximum number of inodes in the volume", + []string{"namespace", "persistentvolumeclaim"}, nil, + ) + volumeStatsInodesFreeDesc = prometheus.NewDesc( + prometheus.BuildFQName("", metrics.KubeletSubsystem, metrics.VolumeStatsInodesFreeKey), + "Number of free inodes in the volume", + []string{"namespace", "persistentvolumeclaim"}, nil, + ) + volumeStatsInodesUsedDesc = prometheus.NewDesc( + prometheus.BuildFQName("", metrics.KubeletSubsystem, metrics.VolumeStatsInodesUsedKey), + "Number of used inodes in the volume", + []string{"namespace", "persistentvolumeclaim"}, nil, + ) +) + +type volumeStatsCollecotr struct { + statsProvider serverstats.StatsProvider +} + +// NewVolumeStatsCollector creates a volume stats prometheus collector. +func NewVolumeStatsCollector(statsProvider serverstats.StatsProvider) prometheus.Collector { + return &volumeStatsCollecotr{statsProvider: statsProvider} +} + +// Describe implements the prometheus.Collector interface. +func (collector *volumeStatsCollecotr) Describe(ch chan<- *prometheus.Desc) { + ch <- volumeStatsCapacityBytesDesc + ch <- volumeStatsAvailableBytesDesc + ch <- volumeStatsUsedBytesDesc + ch <- volumeStatsInodesDesc + ch <- volumeStatsInodesFreeDesc + ch <- volumeStatsInodesUsedDesc +} + +// Collect implements the prometheus.Collector interface. +func (collector *volumeStatsCollecotr) Collect(ch chan<- prometheus.Metric) { + podStats, err := collector.statsProvider.ListPodStats() + if err != nil { + return + } + addGauge := func(desc *prometheus.Desc, pvcRef *stats.PVCReference, v float64, lv ...string) { + lv = append([]string{pvcRef.Namespace, pvcRef.Name}, lv...) + metric, err := prometheus.NewConstMetric(desc, prometheus.GaugeValue, v, lv...) + if err != nil { + glog.Warningf("Failed to generate metric: %v", err) + return + } + ch <- metric + } + allPVCs := sets.String{} + for _, podStat := range podStats { + if podStat.VolumeStats == nil { + continue + } + for _, volumeStat := range podStat.VolumeStats { + pvcRef := volumeStat.PVCRef + if pvcRef == nil { + // ignore if no PVC reference + continue + } + pvcUniqStr := pvcRef.Namespace + "/" + pvcRef.Name + if allPVCs.Has(pvcUniqStr) { + // ignore if already collected + continue + } + addGauge(volumeStatsCapacityBytesDesc, pvcRef, float64(*volumeStat.CapacityBytes)) + addGauge(volumeStatsAvailableBytesDesc, pvcRef, float64(*volumeStat.AvailableBytes)) + addGauge(volumeStatsUsedBytesDesc, pvcRef, float64(*volumeStat.UsedBytes)) + addGauge(volumeStatsInodesDesc, pvcRef, float64(*volumeStat.Inodes)) + addGauge(volumeStatsInodesFreeDesc, pvcRef, float64(*volumeStat.InodesFree)) + addGauge(volumeStatsInodesUsedDesc, pvcRef, float64(*volumeStat.InodesUsed)) + allPVCs.Insert(pvcUniqStr) + } + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/volume_stats_test.go b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/volume_stats_test.go new file mode 100644 index 000000000000..903169d00da5 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/collectors/volume_stats_test.go @@ -0,0 +1,135 @@ +/* +Copyright 2018 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 collectors + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + statsapi "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1" + statstest "k8s.io/kubernetes/pkg/kubelet/server/stats/testing" +) + +func newUint64Pointer(i uint64) *uint64 { + return &i +} + +func TestVolumeStatsCollector(t *testing.T) { + // Fixed metadata on type and help text. We prepend this to every expected + // output so we only have to modify a single place when doing adjustments. + const metadata = ` + # HELP kubelet_volume_stats_available_bytes Number of available bytes in the volume + # TYPE kubelet_volume_stats_available_bytes gauge + # HELP kubelet_volume_stats_capacity_bytes Capacity in bytes of the volume + # TYPE kubelet_volume_stats_capacity_bytes gauge + # HELP kubelet_volume_stats_inodes Maximum number of inodes in the volume + # TYPE kubelet_volume_stats_inodes gauge + # HELP kubelet_volume_stats_inodes_free Number of free inodes in the volume + # TYPE kubelet_volume_stats_inodes_free gauge + # HELP kubelet_volume_stats_inodes_used Number of used inodes in the volume + # TYPE kubelet_volume_stats_inodes_used gauge + # HELP kubelet_volume_stats_used_bytes Number of used bytes in the volume + # TYPE kubelet_volume_stats_used_bytes gauge + ` + + var ( + podStats = []statsapi.PodStats{ + { + PodRef: statsapi.PodReference{Name: "test-pod", Namespace: "test-namespace", UID: "UID_test-pod"}, + StartTime: metav1.Now(), + VolumeStats: []statsapi.VolumeStats{ + { + FsStats: statsapi.FsStats{ + Time: metav1.Now(), + AvailableBytes: newUint64Pointer(5.663154176e+09), + CapacityBytes: newUint64Pointer(1.0434699264e+10), + UsedBytes: newUint64Pointer(4.21789696e+09), + InodesFree: newUint64Pointer(655344), + Inodes: newUint64Pointer(655360), + InodesUsed: newUint64Pointer(16), + }, + Name: "test", + PVCRef: nil, + }, + { + FsStats: statsapi.FsStats{ + Time: metav1.Now(), + AvailableBytes: newUint64Pointer(5.663154176e+09), + CapacityBytes: newUint64Pointer(1.0434699264e+10), + UsedBytes: newUint64Pointer(4.21789696e+09), + InodesFree: newUint64Pointer(655344), + Inodes: newUint64Pointer(655360), + InodesUsed: newUint64Pointer(16), + }, + Name: "test", + PVCRef: &statsapi.PVCReference{ + Name: "testpvc", + Namespace: "testns", + }, + }, + }, + }, + { + // Another pod references the same PVC (test-namespace/testpvc). + PodRef: statsapi.PodReference{Name: "test-pod-2", Namespace: "test-namespace", UID: "UID_test-pod"}, + StartTime: metav1.Now(), + VolumeStats: []statsapi.VolumeStats{ + { + FsStats: statsapi.FsStats{ + Time: metav1.Now(), + AvailableBytes: newUint64Pointer(5.663154176e+09), + CapacityBytes: newUint64Pointer(1.0434699264e+10), + UsedBytes: newUint64Pointer(4.21789696e+09), + InodesFree: newUint64Pointer(655344), + Inodes: newUint64Pointer(655360), + InodesUsed: newUint64Pointer(16), + }, + Name: "test", + PVCRef: &statsapi.PVCReference{ + Name: "testpvc", + Namespace: "testns", + }, + }, + }, + }, + } + + want = metadata + ` + kubelet_volume_stats_available_bytes{namespace="testns",persistentvolumeclaim="testpvc"} 5.663154176e+09 + kubelet_volume_stats_capacity_bytes{namespace="testns",persistentvolumeclaim="testpvc"} 1.0434699264e+10 + kubelet_volume_stats_inodes{namespace="testns",persistentvolumeclaim="testpvc"} 655360 + kubelet_volume_stats_inodes_free{namespace="testns",persistentvolumeclaim="testpvc"} 655344 + kubelet_volume_stats_inodes_used{namespace="testns",persistentvolumeclaim="testpvc"} 16 + kubelet_volume_stats_used_bytes{namespace="testns",persistentvolumeclaim="testpvc"} 4.21789696e+09 + ` + + metrics = []string{ + "kubelet_volume_stats_available_bytes", + "kubelet_volume_stats_capacity_bytes", + "kubelet_volume_stats_inodes", + "kubelet_volume_stats_inodes_free", + "kubelet_volume_stats_inodes_used", + "kubelet_volume_stats_used_bytes", + } + ) + + mockStatsProvider := new(statstest.StatsProvider) + mockStatsProvider.On("ListPodStats").Return(podStats, nil) + if err := gatherAndCompare(&volumeStatsCollecotr{statsProvider: mockStatsProvider}, want, metrics); err != nil { + t.Errorf("unexpected collecting result:\n%s", err) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go index 0fc10dc189a4..4e9470f5a52e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go @@ -134,54 +134,6 @@ var ( }, []string{"eviction_signal"}, ) - VolumeStatsCapacityBytes = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: VolumeStatsCapacityBytesKey, - Help: "Capacity in bytes of the volume", - }, - []string{"namespace", "persistentvolumeclaim"}, - ) - VolumeStatsAvailableBytes = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: VolumeStatsAvailableBytesKey, - Help: "Number of available bytes in the volume", - }, - []string{"namespace", "persistentvolumeclaim"}, - ) - VolumeStatsUsedBytes = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: VolumeStatsUsedBytesKey, - Help: "Number of used bytes in the volume", - }, - []string{"namespace", "persistentvolumeclaim"}, - ) - VolumeStatsInodes = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: VolumeStatsInodesKey, - Help: "Maximum number of inodes in the volume", - }, - []string{"namespace", "persistentvolumeclaim"}, - ) - VolumeStatsInodesFree = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: VolumeStatsInodesFreeKey, - Help: "Number of free inodes in the volume", - }, - []string{"namespace", "persistentvolumeclaim"}, - ) - VolumeStatsInodesUsed = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: VolumeStatsInodesUsedKey, - Help: "Number of used inodes in the volume", - }, - []string{"namespace", "persistentvolumeclaim"}, - ) DevicePluginRegistrationCount = prometheus.NewCounterVec( prometheus.CounterOpts{ Subsystem: KubeletSubsystem, @@ -203,7 +155,7 @@ var ( var registerMetrics sync.Once // Register all metrics. -func Register(containerCache kubecontainer.RuntimeCache) { +func Register(containerCache kubecontainer.RuntimeCache, collectors ...prometheus.Collector) { // Register the metrics. registerMetrics.Do(func() { prometheus.MustRegister(PodWorkerLatency) @@ -218,14 +170,11 @@ func Register(containerCache kubecontainer.RuntimeCache) { prometheus.MustRegister(RuntimeOperationsLatency) prometheus.MustRegister(RuntimeOperationsErrors) prometheus.MustRegister(EvictionStatsAge) - prometheus.MustRegister(VolumeStatsCapacityBytes) - prometheus.MustRegister(VolumeStatsAvailableBytes) - prometheus.MustRegister(VolumeStatsUsedBytes) - prometheus.MustRegister(VolumeStatsInodes) - prometheus.MustRegister(VolumeStatsInodesFree) - prometheus.MustRegister(VolumeStatsInodesUsed) prometheus.MustRegister(DevicePluginRegistrationCount) prometheus.MustRegister(DevicePluginAllocationLatency) + for _, collector := range collectors { + prometheus.MustRegister(collector) + } }) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/BUILD b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/BUILD index 00140b342bf3..e197e0f5dd49 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/BUILD @@ -16,7 +16,6 @@ go_library( "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", "//pkg/kubelet/cm:go_default_library", "//pkg/kubelet/container:go_default_library", - "//pkg/kubelet/metrics:go_default_library", "//pkg/kubelet/util/format:go_default_library", "//pkg/volume:go_default_library", "//vendor/github.com/emicklei/go-restful:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/volume_stat_calculator.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/volume_stat_calculator.go index 87355870cc4d..2c535f56241a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/volume_stat_calculator.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/volume_stat_calculator.go @@ -24,7 +24,6 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/wait" stats "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1" - "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/util/format" "k8s.io/kubernetes/pkg/volume" @@ -122,8 +121,6 @@ func (s *volumeStatCalculator) calcAndStoreStats() { Name: pvcSource.ClaimName, Namespace: s.pod.GetNamespace(), } - // Set the PVC's prometheus metrics - s.setPVCMetrics(pvcRef, metric) } volumeStats := s.parsePodVolumeStats(name, pvcRef, metric, volSpec) if isVolumeEphemeral(volSpec) { @@ -163,13 +160,3 @@ func isVolumeEphemeral(volume v1.Volume) bool { } return false } - -// setPVCMetrics sets the given PVC's prometheus metrics to match the given volume.Metrics -func (s *volumeStatCalculator) setPVCMetrics(pvcRef *stats.PVCReference, metric *volume.Metrics) { - metrics.VolumeStatsAvailableBytes.WithLabelValues(pvcRef.Namespace, pvcRef.Name).Set(float64(metric.Available.Value())) - metrics.VolumeStatsCapacityBytes.WithLabelValues(pvcRef.Namespace, pvcRef.Name).Set(float64(metric.Capacity.Value())) - metrics.VolumeStatsUsedBytes.WithLabelValues(pvcRef.Namespace, pvcRef.Name).Set(float64(metric.Used.Value())) - metrics.VolumeStatsInodes.WithLabelValues(pvcRef.Namespace, pvcRef.Name).Set(float64(metric.Inodes.Value())) - metrics.VolumeStatsInodesFree.WithLabelValues(pvcRef.Namespace, pvcRef.Name).Set(float64(metric.InodesFree.Value())) - metrics.VolumeStatsInodesUsed.WithLabelValues(pvcRef.Namespace, pvcRef.Name).Set(float64(metric.InodesUsed.Value())) -}