Add Metrics About StorageClass
This commit is contained in:
parent
332c90f3be
commit
c18dfa26cf
|
|
@ -60,6 +60,7 @@ Per group of metrics there is one file for each metrics. See each file for speci
|
|||
- [ResourceQuota Metrics](resourcequota-metrics.md)
|
||||
- [Service Metrics](service-metrics.md)
|
||||
- [StatefulSet Metrics](statefulset-metrics.md)
|
||||
- [StorageClass Metrics](storageclass-metrics.md)
|
||||
- [Namespace Metrics](namespace-metrics.md)
|
||||
- [Horizontal Pod Autoscaler Metrics](horizontalpodautoscaler-metrics.md)
|
||||
- [Endpoint Metrics](endpoint-metrics.md)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
# StorageClass Metrics
|
||||
|
||||
| Metric name| Metric type | Labels/tags | Status |
|
||||
| ---------- | ----------- | ----------- | ----------- |
|
||||
| kube_storageclass_info | Gauge | `storageclass`=<storageclass-name> <br> `provisioner`=<storageclass-provisioner> <br> `reclaimPolicy`=<storageclass-reclaimPolicy> <br> `volumeBindingMode`=<storageclass-volumeBindingMode> | STABLE |
|
||||
| kube_storageclass_labels | Gauge | `storageclass`=<storageclass-name> <br> `label_STORAGECLASS_LABEL`=<STORAGECLASS_LABEL> | STABLE |
|
||||
| kube_storageclass_created | Gauge | `storageclass`=<storageclass-name> | STABLE |
|
||||
| kube_storageclass_metadata_resource_version | Gauge | `storageclass`=<storageclass-name> <br> `resource_version`=<storageclass-resource-version> | STABLE |
|
||||
|
|
@ -31,6 +31,7 @@ import (
|
|||
v1 "k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
policy "k8s.io/api/policy/v1beta1"
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
coll "k8s.io/kube-state-metrics/pkg/collector"
|
||||
|
|
@ -135,6 +136,7 @@ var availableCollectors = map[string]func(f *Builder) *coll.Collector{
|
|||
"secrets": func(b *Builder) *coll.Collector { return b.buildSecretCollector() },
|
||||
"services": func(b *Builder) *coll.Collector { return b.buildServiceCollector() },
|
||||
"statefulsets": func(b *Builder) *coll.Collector { return b.buildStatefulSetCollector() },
|
||||
"storageclasses": func(b *Builder) *coll.Collector { return b.buildStorageClassCollector() },
|
||||
}
|
||||
|
||||
func (b *Builder) buildConfigMapCollector() *coll.Collector {
|
||||
|
|
@ -217,6 +219,10 @@ func (b *Builder) buildStatefulSetCollector() *coll.Collector {
|
|||
return b.buildCollector(statefulSetMetricFamilies, &appsv1.StatefulSet{}, createStatefulSetListWatch)
|
||||
}
|
||||
|
||||
func (b *Builder) buildStorageClassCollector() *coll.Collector {
|
||||
return b.buildCollector(storageClassMetricFamilies, &storagev1.StorageClass{}, createStorageClassListWatch)
|
||||
}
|
||||
|
||||
func (b *Builder) buildPodCollector() *coll.Collector {
|
||||
return b.buildCollector(podMetricFamilies, &v1.Pod{}, createPodListWatch)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors All rights reserved.
|
||||
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 collector
|
||||
|
||||
import (
|
||||
"k8s.io/kube-state-metrics/pkg/metric"
|
||||
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
var (
|
||||
descStorageClassLabelsName = "kube_storageclass_labels"
|
||||
descStorageClassLabelsHelp = "Kubernetes labels converted to Prometheus labels."
|
||||
descStorageClassLabelsDefaultLabels = []string{"storageclass"}
|
||||
|
||||
storageClassMetricFamilies = []metric.FamilyGenerator{
|
||||
{
|
||||
Name: "kube_storageclass_info",
|
||||
Type: metric.Gauge,
|
||||
Help: "Information about storageclass.",
|
||||
GenerateFunc: wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family {
|
||||
m := metric.Metric{
|
||||
LabelKeys: []string{"provisioner", "reclaimPolicy", "volumeBindingMode"},
|
||||
LabelValues: []string{s.Provisioner, string(*s.ReclaimPolicy), string(*s.VolumeBindingMode)},
|
||||
Value: 1,
|
||||
}
|
||||
return &metric.Family{Metrics: []*metric.Metric{&m}}
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: "kube_storageclass_created",
|
||||
Type: metric.Gauge,
|
||||
Help: "Unix creation timestamp",
|
||||
GenerateFunc: wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family {
|
||||
ms := []*metric.Metric{}
|
||||
if !s.CreationTimestamp.IsZero() {
|
||||
ms = append(ms, &metric.Metric{
|
||||
Value: float64(s.CreationTimestamp.Unix()),
|
||||
})
|
||||
}
|
||||
return &metric.Family{
|
||||
Metrics: ms,
|
||||
}
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: "kube_storageclass_metadata_resource_version",
|
||||
Type: metric.Gauge,
|
||||
Help: "Resource version representing a specific version of storageclass.",
|
||||
GenerateFunc: wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family {
|
||||
return &metric.Family{
|
||||
Metrics: []*metric.Metric{
|
||||
{
|
||||
LabelKeys: []string{"resource_version"},
|
||||
LabelValues: []string{s.ObjectMeta.ResourceVersion},
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: descStorageClassLabelsName,
|
||||
Type: metric.Gauge,
|
||||
Help: descStorageClassLabelsHelp,
|
||||
GenerateFunc: wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family {
|
||||
labelKeys, labelValues := kubeLabelsToPrometheusLabels(s.Labels)
|
||||
return &metric.Family{
|
||||
Metrics: []*metric.Metric{
|
||||
{
|
||||
LabelKeys: labelKeys,
|
||||
LabelValues: labelValues,
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
}),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func wrapStorageClassFunc(f func(*storagev1.StorageClass) *metric.Family) func(interface{}) *metric.Family {
|
||||
return func(obj interface{}) *metric.Family {
|
||||
storageClass := obj.(*storagev1.StorageClass)
|
||||
|
||||
metricFamily := f(storageClass)
|
||||
|
||||
for _, m := range metricFamily.Metrics {
|
||||
m.LabelKeys = append(descStorageClassLabelsDefaultLabels, m.LabelKeys...)
|
||||
m.LabelValues = append([]string{storageClass.Name}, m.LabelValues...)
|
||||
}
|
||||
|
||||
return metricFamily
|
||||
}
|
||||
}
|
||||
|
||||
func createStorageClassListWatch(kubeClient clientset.Interface, ns string) cache.ListerWatcher {
|
||||
return &cache.ListWatch{
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
return kubeClient.StorageV1().StorageClasses().List(opts)
|
||||
},
|
||||
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return kubeClient.StorageV1().StorageClasses().Watch(opts)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors All rights reserved.
|
||||
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 collector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kube-state-metrics/pkg/metric"
|
||||
)
|
||||
|
||||
func TestStorageClassCollector(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.
|
||||
|
||||
startTime := 1501569018
|
||||
metav1StartTime := metav1.Unix(int64(startTime), 0)
|
||||
reclaimPolicy := v1.PersistentVolumeReclaimDelete
|
||||
volumeBindingMode := storagev1.VolumeBindingImmediate
|
||||
|
||||
const metadata = `
|
||||
# HELP kube_storageclass_labels Kubernetes labels converted to Prometheus labels.
|
||||
# TYPE kube_storageclass_labels gauge
|
||||
# HELP kube_storageclass_info Information about storageclass.
|
||||
# TYPE kube_storageclass_info gauge
|
||||
# HELP kube_storageclass_created Unix creation timestamp
|
||||
# TYPE kube_storageclass_created gauge
|
||||
# HELP kube_storageclass_metadata_resource_version Resource version representing a specific version of secret.
|
||||
# TYPE kube_storageclass_metadata_resource_version gauge
|
||||
`
|
||||
cases := []generateMetricsTestCase{
|
||||
{
|
||||
Obj: &storagev1.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test_storageclass-info",
|
||||
},
|
||||
Provisioner: "kubernetes.io/rbd",
|
||||
ReclaimPolicy: &reclaimPolicy,
|
||||
VolumeBindingMode: &volumeBindingMode,
|
||||
},
|
||||
Want: `
|
||||
kube_storageclass_info{storageclass="test_storageclass-info",provisioner="kubernetes.io/rbd",reclaimPolicy="Delete",volumeBindingMode="Immediate"} 1
|
||||
`,
|
||||
MetricNames: []string{
|
||||
"kube_storageclass_info",
|
||||
},
|
||||
},
|
||||
{
|
||||
Obj: &storagev1.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test_kube_storageclass_created",
|
||||
CreationTimestamp: metav1StartTime,
|
||||
},
|
||||
Provisioner: "kubernetes.io/rbd",
|
||||
ReclaimPolicy: &reclaimPolicy,
|
||||
VolumeBindingMode: &volumeBindingMode,
|
||||
},
|
||||
Want: `
|
||||
kube_storageclass_created{storageclass="test_kube_storageclass_created"} 1.501569018e+09
|
||||
`,
|
||||
MetricNames: []string{
|
||||
"kube_storageclass_created",
|
||||
},
|
||||
},
|
||||
{
|
||||
Obj: &storagev1.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test_kube_storageclass_resource_version",
|
||||
ResourceVersion: "abcdef",
|
||||
},
|
||||
Provisioner: "kubernetes.io/rbd",
|
||||
ReclaimPolicy: &reclaimPolicy,
|
||||
VolumeBindingMode: &volumeBindingMode,
|
||||
},
|
||||
Want: `
|
||||
kube_storageclass_metadata_resource_version{storageclass="test_kube_storageclass_resource_version",resource_version="abcdef"} 1
|
||||
`,
|
||||
MetricNames: []string{
|
||||
"kube_storageclass_metadata_resource_version",
|
||||
},
|
||||
},
|
||||
{
|
||||
Obj: &storagev1.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test_storageclass-labels",
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Provisioner: "kubernetes.io/rbd",
|
||||
ReclaimPolicy: &reclaimPolicy,
|
||||
VolumeBindingMode: &volumeBindingMode,
|
||||
},
|
||||
Want: `
|
||||
kube_storageclass_labels{storageclass="test_storageclass-labels",label_foo="bar"} 1
|
||||
`,
|
||||
MetricNames: []string{
|
||||
"kube_storageclass_labels",
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, c := range cases {
|
||||
c.Func = metric.ComposeMetricGenFuncs(storageClassMetricFamilies)
|
||||
if err := c.run(); err != nil {
|
||||
t.Errorf("unexpected collecting result in %vth run:\n%s", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,4 +50,8 @@ rules:
|
|||
resources:
|
||||
- certificatesigningrequests
|
||||
verbs: ["list", "watch"]
|
||||
- apiGroups: ["storage.k8s.io"]
|
||||
resources:
|
||||
- storageclasses
|
||||
verbs: ["list", "watch"]
|
||||
|
||||
|
|
|
|||
|
|
@ -48,5 +48,6 @@ var (
|
|||
"secrets": struct{}{},
|
||||
"services": struct{}{},
|
||||
"statefulsets": struct{}{},
|
||||
"storageclasses": struct{}{},
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: storageclass
|
||||
provisioner: kubernetes.io/rbd
|
||||
reclaimPolicy: Delete
|
||||
volumeBindingMode: Immediate
|
||||
|
|
@ -126,6 +126,7 @@ k8s.io/api/certificates/v1beta1
|
|||
k8s.io/api/core/v1
|
||||
k8s.io/api/extensions/v1beta1
|
||||
k8s.io/api/policy/v1beta1
|
||||
k8s.io/api/storage/v1
|
||||
k8s.io/api/apps/v1beta1
|
||||
k8s.io/api/admissionregistration/v1beta1
|
||||
k8s.io/api/autoscaling/v1
|
||||
|
|
@ -151,7 +152,6 @@ k8s.io/api/scheduling/v1
|
|||
k8s.io/api/scheduling/v1alpha1
|
||||
k8s.io/api/scheduling/v1beta1
|
||||
k8s.io/api/settings/v1alpha1
|
||||
k8s.io/api/storage/v1
|
||||
k8s.io/api/storage/v1alpha1
|
||||
k8s.io/api/storage/v1beta1
|
||||
# k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1
|
||||
|
|
|
|||
Loading…
Reference in New Issue