pkg/collectors: Refactor hpa collector
This commit is contained in:
parent
3778527880
commit
ce5c90fbf1
|
|
@ -178,6 +178,13 @@ func TestFullScrapeCycle(t *testing.T) {
|
|||
# HELP kube_endpoint_labels Kubernetes labels converted to Prometheus labels.
|
||||
# HELP kube_endpoint_address_available Number of addresses available in endpoint.
|
||||
# HELP kube_endpoint_address_not_ready Number of addresses not ready in endpoint
|
||||
# HELP kube_hpa_metadata_generation The generation observed by the HorizontalPodAutoscaler controller.
|
||||
# HELP kube_hpa_spec_max_replicas Upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.
|
||||
# HELP kube_hpa_spec_min_replicas Lower limit for the number of pods that can be set by the autoscaler, default 1.
|
||||
# HELP kube_hpa_status_current_replicas Current number of replicas of pods managed by this autoscaler.
|
||||
# HELP kube_hpa_status_desired_replicas Desired number of replicas of pods managed by this autoscaler.
|
||||
# HELP kube_hpa_labels Kubernetes labels converted to Prometheus labels.
|
||||
# HELP kube_hpa_status_condition The condition of this autoscaler.
|
||||
# HELP kube_job_labels Kubernetes labels converted to Prometheus labels.
|
||||
# HELP kube_job_info Information about job.
|
||||
# HELP kube_job_created Unix creation timestamp
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import (
|
|||
"k8s.io/kube-state-metrics/pkg/options"
|
||||
|
||||
apps "k8s.io/api/apps/v1beta1"
|
||||
// autoscaling "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
"k8s.io/api/core/v1"
|
||||
|
|
@ -121,6 +121,7 @@ var availableCollectors = map[string]func(f *Builder) *Collector{
|
|||
"daemonsets": func(b *Builder) *Collector { return b.buildDaemonSetCollector() },
|
||||
"deployments": func(b *Builder) *Collector { return b.buildDeploymentCollector() },
|
||||
"endpoints": func(b *Builder) *Collector { return b.buildEndpointsCollector() },
|
||||
"horizontalpodautoscalers": func(b *Builder) *Collector { return b.buildHPACollector() },
|
||||
"jobs": func(b *Builder) *Collector { return b.buildJobCollector() },
|
||||
"limitranges": func(b *Builder) *Collector { return b.buildLimitRangeCollector() },
|
||||
"namespaces": func(b *Builder) *Collector { return b.buildNamespaceCollector() },
|
||||
|
|
@ -135,7 +136,6 @@ var availableCollectors = map[string]func(f *Builder) *Collector{
|
|||
"secrets": func(b *Builder) *Collector { return b.buildSecretCollector() },
|
||||
"services": func(b *Builder) *Collector { return b.buildServiceCollector() },
|
||||
"statefulsets": func(b *Builder) *Collector { return b.buildStatefulSetCollector() },
|
||||
// "horizontalpodautoscalers": func(b *Builder) *Collector { return b.buildHPACollector() },
|
||||
}
|
||||
|
||||
func (b *Builder) buildConfigMapCollector() *Collector {
|
||||
|
|
@ -213,6 +213,21 @@ func (b *Builder) buildEndpointsCollector() *Collector {
|
|||
return NewCollector(store)
|
||||
}
|
||||
|
||||
func (b *Builder) buildHPACollector() *Collector {
|
||||
filteredMetricFamilies := filterMetricFamilies(b.whiteBlackList, hpaMetricFamilies)
|
||||
composedMetricGenFuncs := composeMetricGenFuncs(filteredMetricFamilies)
|
||||
|
||||
helpTexts := extractHelpText(filteredMetricFamilies)
|
||||
|
||||
store := metricsstore.NewMetricsStore(
|
||||
helpTexts,
|
||||
composedMetricGenFuncs,
|
||||
)
|
||||
reflectorPerNamespace(b.ctx, b.kubeClient, &autoscaling.HorizontalPodAutoscaler{}, store, b.namespaces, createHPAListWatch)
|
||||
|
||||
return NewCollector(store)
|
||||
}
|
||||
|
||||
func (b *Builder) buildJobCollector() *Collector {
|
||||
filteredMetricFamilies := filterMetricFamilies(b.whiteBlackList, jobMetricFamilies)
|
||||
composedMetricGenFuncs := composeMetricGenFuncs(filteredMetricFamilies)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
Copyright 2016 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 collectors
|
||||
|
||||
import (
|
||||
"k8s.io/kube-state-metrics/pkg/metrics"
|
||||
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta1"
|
||||
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 (
|
||||
descHorizontalPodAutoscalerLabelsName = "kube_hpa_labels"
|
||||
descHorizontalPodAutoscalerLabelsHelp = "Kubernetes labels converted to Prometheus labels."
|
||||
descHorizontalPodAutoscalerLabelsDefaultLabels = []string{"namespace", "hpa"}
|
||||
|
||||
hpaMetricFamilies = []metrics.FamilyGenerator{
|
||||
metrics.FamilyGenerator{
|
||||
Name: "kube_hpa_metadata_generation",
|
||||
Help: "The generation observed by the HorizontalPodAutoscaler controller.",
|
||||
GenerateFunc: wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) metrics.Family {
|
||||
return metrics.Family{&metrics.Metric{
|
||||
Name: "kube_hpa_metadata_generation",
|
||||
Value: float64(a.ObjectMeta.Generation),
|
||||
}}
|
||||
}),
|
||||
},
|
||||
metrics.FamilyGenerator{
|
||||
Name: "kube_hpa_spec_max_replicas",
|
||||
Help: "Upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.",
|
||||
GenerateFunc: wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) metrics.Family {
|
||||
return metrics.Family{&metrics.Metric{
|
||||
Name: "kube_hpa_spec_max_replicas",
|
||||
Value: float64(a.Spec.MaxReplicas),
|
||||
}}
|
||||
}),
|
||||
},
|
||||
metrics.FamilyGenerator{
|
||||
Name: "kube_hpa_spec_min_replicas",
|
||||
Help: "Lower limit for the number of pods that can be set by the autoscaler, default 1.",
|
||||
GenerateFunc: wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) metrics.Family {
|
||||
return metrics.Family{&metrics.Metric{
|
||||
Name: "kube_hpa_spec_min_replicas",
|
||||
Value: float64(*a.Spec.MinReplicas),
|
||||
}}
|
||||
}),
|
||||
},
|
||||
metrics.FamilyGenerator{
|
||||
Name: "kube_hpa_status_current_replicas",
|
||||
Help: "Current number of replicas of pods managed by this autoscaler.",
|
||||
GenerateFunc: wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) metrics.Family {
|
||||
return metrics.Family{&metrics.Metric{
|
||||
Name: "kube_hpa_status_current_replicas",
|
||||
Value: float64(a.Status.CurrentReplicas),
|
||||
}}
|
||||
}),
|
||||
},
|
||||
metrics.FamilyGenerator{
|
||||
Name: "kube_hpa_status_desired_replicas",
|
||||
Help: "Desired number of replicas of pods managed by this autoscaler.",
|
||||
GenerateFunc: wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) metrics.Family {
|
||||
return metrics.Family{&metrics.Metric{
|
||||
Name: "kube_hpa_status_desired_replicas",
|
||||
Value: float64(a.Status.DesiredReplicas),
|
||||
}}
|
||||
}),
|
||||
},
|
||||
metrics.FamilyGenerator{
|
||||
Name: descHorizontalPodAutoscalerLabelsName,
|
||||
Help: descHorizontalPodAutoscalerLabelsHelp,
|
||||
GenerateFunc: wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) metrics.Family {
|
||||
labelKeys, labelValues := kubeLabelsToPrometheusLabels(a.Labels)
|
||||
return metrics.Family{&metrics.Metric{
|
||||
Name: descHorizontalPodAutoscalerLabelsName,
|
||||
LabelKeys: labelKeys,
|
||||
LabelValues: labelValues,
|
||||
Value: 1,
|
||||
}}
|
||||
}),
|
||||
},
|
||||
metrics.FamilyGenerator{
|
||||
Name: "kube_hpa_status_condition",
|
||||
Help: "The condition of this autoscaler.",
|
||||
GenerateFunc: wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) metrics.Family {
|
||||
f := metrics.Family{}
|
||||
|
||||
for _, c := range a.Status.Conditions {
|
||||
metrics := addConditionMetrics(c.Status)
|
||||
|
||||
for _, m := range metrics {
|
||||
metric := m
|
||||
metric.Name = "kube_hpa_status_condition"
|
||||
metric.LabelKeys = []string{"condition", "status"}
|
||||
metric.LabelValues = append(metric.LabelValues, string(c.Type))
|
||||
f = append(f, metric)
|
||||
}
|
||||
}
|
||||
|
||||
return f
|
||||
}),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func wrapHPAFunc(f func(*autoscaling.HorizontalPodAutoscaler) metrics.Family) func(interface{}) metrics.Family {
|
||||
return func(obj interface{}) metrics.Family {
|
||||
hpa := obj.(*autoscaling.HorizontalPodAutoscaler)
|
||||
|
||||
metricFamily := f(hpa)
|
||||
|
||||
for _, m := range metricFamily {
|
||||
m.LabelKeys = append(descHorizontalPodAutoscalerLabelsDefaultLabels, m.LabelKeys...)
|
||||
m.LabelValues = append([]string{hpa.Namespace, hpa.Name}, m.LabelValues...)
|
||||
}
|
||||
|
||||
return metricFamily
|
||||
}
|
||||
}
|
||||
|
||||
func createHPAListWatch(kubeClient clientset.Interface, ns string) cache.ListWatch {
|
||||
return cache.ListWatch{
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
return kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers(ns).List(opts)
|
||||
},
|
||||
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return kubeClient.AutoscalingV2beta1().HorizontalPodAutoscalers(ns).Watch(opts)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright 2016 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 collectors
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var (
|
||||
hpa1MinReplicas int32 = 2
|
||||
)
|
||||
|
||||
func TestHPACollector(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 kube_hpa_metadata_generation The generation observed by the HorizontalPodAutoscaler controller.
|
||||
# TYPE kube_hpa_metadata_generation gauge
|
||||
# HELP kube_hpa_spec_max_replicas Upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.
|
||||
# TYPE kube_hpa_spec_max_replicas gauge
|
||||
# HELP kube_hpa_spec_min_replicas Lower limit for the number of pods that can be set by the autoscaler, default 1.
|
||||
# TYPE kube_hpa_spec_min_replicas gauge
|
||||
# HELP kube_hpa_status_current_replicas Current number of replicas of pods managed by this autoscaler.
|
||||
# TYPE kube_hpa_status_current_replicas gauge
|
||||
# HELP kube_hpa_status_desired_replicas Desired number of replicas of pods managed by this autoscaler.
|
||||
# TYPE kube_hpa_status_desired_replicas gauge
|
||||
`
|
||||
cases := []generateMetricsTestCase{
|
||||
{
|
||||
// Verify populating base metrics.
|
||||
Obj: &autoscaling.HorizontalPodAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Generation: 2,
|
||||
Name: "hpa1",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||
MaxReplicas: 4,
|
||||
MinReplicas: &hpa1MinReplicas,
|
||||
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "Deployment",
|
||||
Name: "deployment1",
|
||||
},
|
||||
},
|
||||
Status: autoscaling.HorizontalPodAutoscalerStatus{
|
||||
CurrentReplicas: 2,
|
||||
DesiredReplicas: 2,
|
||||
},
|
||||
},
|
||||
Want: `
|
||||
kube_hpa_metadata_generation{hpa="hpa1",namespace="ns1"} 2
|
||||
kube_hpa_spec_max_replicas{hpa="hpa1",namespace="ns1"} 4
|
||||
kube_hpa_spec_min_replicas{hpa="hpa1",namespace="ns1"} 2
|
||||
kube_hpa_status_current_replicas{hpa="hpa1",namespace="ns1"} 2
|
||||
kube_hpa_status_desired_replicas{hpa="hpa1",namespace="ns1"} 2
|
||||
`,
|
||||
MetricNames: []string{
|
||||
"kube_hpa_metadata_generation",
|
||||
"kube_hpa_spec_max_replicas",
|
||||
"kube_hpa_spec_min_replicas",
|
||||
"kube_hpa_status_current_replicas",
|
||||
"kube_hpa_status_desired_replicas",
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, c := range cases {
|
||||
c.Func = composeMetricGenFuncs(hpaMetricFamilies)
|
||||
if err := c.run(); err != nil {
|
||||
t.Errorf("unexpected collecting result in %vth run:\n%s", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue