Skip to content

Commit

Permalink
[fix] make metrics generic + use container label
Browse files Browse the repository at this point in the history
  • Loading branch information
milesbxf committed Jun 18, 2019
1 parent 9fd1880 commit 6d9eb11
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 231 deletions.
256 changes: 49 additions & 207 deletions internal/store/vpa.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019 The Kubernetes Authors All rights reserved.
Copyright 2018 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.
Expand All @@ -23,6 +23,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/kube-state-metrics/pkg/constant"

autoscaling "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1beta2"
vpaclientset "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/client/clientset/versioned"
Expand Down Expand Up @@ -93,249 +94,78 @@ var (
}),
},
{
Name: "kube_vpa_container_resource_policy_min_cpu_cores",
Name: "kube_vpa_container_resource_policy_min",
Type: metric.Gauge,
Help: "Minimum CPU cores the VPA can set for containers matching the name.",
Help: "Minimum resources the VPA can set for containers matching the name.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
for _, c := range a.Spec.ResourcePolicy.ContainerPolicies {
min := c.MinAllowed
if cpu, ok := min[v1.ResourceCPU]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(cpu.MilliValue()) / 1000,
})
}
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_resource_policy_min_memory_bytes",
Type: metric.Gauge,
Help: "Minimum memory bytes the VPA can set for containers matching the name.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
for _, c := range a.Spec.ResourcePolicy.ContainerPolicies {
min := c.MinAllowed
if mem, ok := min[v1.ResourceMemory]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(mem.Value()),
})
}
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_resource_policy_max_cpu_cores",
Type: metric.Gauge,
Help: "Maximum CPU cores the VPA can set for containers matching the name.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
for _, c := range a.Spec.ResourcePolicy.ContainerPolicies {
max := c.MaxAllowed
if cpu, ok := max[v1.ResourceCPU]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(cpu.MilliValue()) / 1000,
})
}
ms = append(ms, vpaResourcesToMetrics(c.ContainerName, c.MinAllowed)...)

}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_resource_policy_max_memory_bytes",
Name: "kube_vpa_container_resource_policy_max",
Type: metric.Gauge,
Help: "Maximum memory bytes the VPA can set for containers matching the name.",
Help: "Maximum resources the VPA can set for containers matching the name.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
for _, c := range a.Spec.ResourcePolicy.ContainerPolicies {
max := c.MaxAllowed
if mem, ok := max[v1.ResourceMemory]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(mem.Value()),
})
}
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_status_recommendation_lower_bound_cpu_cores",
Type: metric.Gauge,
Help: "Minimum CPU cores the container can use before the VPA updater evicts it.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
if a.Status.Recommendation == nil || a.Status.Recommendation.ContainerRecommendations == nil {
return &metric.Family{
Metrics: ms,
}
}
for _, c := range a.Status.Recommendation.ContainerRecommendations {
v := c.LowerBound
if cpu, ok := v[v1.ResourceCPU]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(cpu.MilliValue()) / 1000,
})
}
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_status_recommendation_lower_bound_memory_bytes",
Type: metric.Gauge,
Help: "Minimum memory bytes the container can use before the VPA updater evicts it.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
if a.Status.Recommendation == nil || a.Status.Recommendation.ContainerRecommendations == nil {
return &metric.Family{
Metrics: ms,
}
}
for _, c := range a.Status.Recommendation.ContainerRecommendations {
v := c.LowerBound
if mem, ok := v[v1.ResourceMemory]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(mem.Value()),
})
}
ms = append(ms, vpaResourcesToMetrics(c.ContainerName, c.MaxAllowed)...)
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_status_recommendation_upper_bound_cpu_cores",
Name: "kube_vpa_container_status_recommendation_lower_bound",
Type: metric.Gauge,
Help: "Maximum CPU cores the container can use before the VPA updater evicts it.",
Help: "Minimum resources the container can use before the VPA updater evicts it.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
if a.Status.Recommendation == nil || a.Status.Recommendation.ContainerRecommendations == nil {
return &metric.Family{
Metrics: ms,
}
}

for _, c := range a.Status.Recommendation.ContainerRecommendations {
v := c.UpperBound
if cpu, ok := v[v1.ResourceCPU]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(cpu.MilliValue()) / 1000,
})
}
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_status_recommendation_upper_bound_memory_bytes",
Type: metric.Gauge,
Help: "Maximum memory bytes the container can use before the VPA updater evicts it.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
if a.Status.Recommendation == nil || a.Status.Recommendation.ContainerRecommendations == nil {
return &metric.Family{
Metrics: ms,
}
}
for _, c := range a.Status.Recommendation.ContainerRecommendations {
v := c.UpperBound
if mem, ok := v[v1.ResourceMemory]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(mem.Value()),
})
}
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_status_recommendation_target_cpu_cores",
Type: metric.Gauge,
Help: "Target CPU cores the VPA recommends for the container.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
if a.Status.Recommendation == nil || a.Status.Recommendation.ContainerRecommendations == nil {
return &metric.Family{
Metrics: ms,
}
}
for _, c := range a.Status.Recommendation.ContainerRecommendations {
v := c.Target
if cpu, ok := v[v1.ResourceCPU]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(cpu.MilliValue()) / 1000,
})
}
ms = append(ms, vpaResourcesToMetrics(c.ContainerName, c.LowerBound)...)
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_status_recommendation_target_memory_bytes",
Name: "kube_vpa_container_status_recommendation_upper_bound",
Type: metric.Gauge,
Help: "Target memory bytes the VPA recommends for the container.",
Help: "Maximum resources the container can use before the VPA updater evicts it.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
if a.Status.Recommendation == nil || a.Status.Recommendation.ContainerRecommendations == nil {
return &metric.Family{
Metrics: ms,
}
}

for _, c := range a.Status.Recommendation.ContainerRecommendations {
v := c.Target
if mem, ok := v[v1.ResourceMemory]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(mem.Value()),
})
}
ms = append(ms, vpaResourcesToMetrics(c.ContainerName, c.UpperBound)...)
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_status_recommendation_uncapped_target_cpu_cores",
Name: "kube_vpa_container_status_recommendation_target",
Type: metric.Gauge,
Help: "Target CPU cores the VPA recommends for the container ignoring bounds.",
Help: "Target resources the VPA recommends for the container.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
if a.Status.Recommendation == nil || a.Status.Recommendation.ContainerRecommendations == nil {
Expand All @@ -344,24 +174,17 @@ var (
}
}
for _, c := range a.Status.Recommendation.ContainerRecommendations {
v := c.UncappedTarget
if cpu, ok := v[v1.ResourceCPU]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(cpu.MilliValue()) / 1000,
})
}
ms = append(ms, vpaResourcesToMetrics(c.ContainerName, c.Target)...)
}
return &metric.Family{
Metrics: ms,
}
}),
},
{
Name: "kube_vpa_container_status_recommendation_uncapped_target_memory_bytes",
Name: "kube_vpa_container_status_recommendation_uncapped_target",
Type: metric.Gauge,
Help: "Target memory bytes the VPA recommends for the container ignoring bounds.",
Help: "Target resources the VPA recommends for the container ignoring bounds.",
GenerateFunc: wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family {
ms := []*metric.Metric{}
if a.Status.Recommendation == nil || a.Status.Recommendation.ContainerRecommendations == nil {
Expand All @@ -370,14 +193,7 @@ var (
}
}
for _, c := range a.Status.Recommendation.ContainerRecommendations {
v := c.UncappedTarget
if mem, ok := v[v1.ResourceMemory]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(mem.Value()),
})
}
ms = append(ms, vpaResourcesToMetrics(c.ContainerName, c.UncappedTarget)...)
}
return &metric.Family{
Metrics: ms,
Expand All @@ -387,6 +203,32 @@ var (
}
)

func vpaResourcesToMetrics(containerName string, resources v1.ResourceList) []*metric.Metric {
ms := []*metric.Metric{}
for resourceName, val := range resources {
switch resourceName {
case v1.ResourceCPU:
ms = append(ms, &metric.Metric{
LabelValues: []string{containerName, sanitizeLabelName(string(resourceName)), string(constant.UnitCore)},
Value: float64(val.MilliValue()) / 1000,
})
case v1.ResourceStorage:
fallthrough
case v1.ResourceEphemeralStorage:
fallthrough
case v1.ResourceMemory:
ms = append(ms, &metric.Metric{
LabelValues: []string{containerName, sanitizeLabelName(string(resourceName)), string(constant.UnitByte)},
Value: float64(val.Value()),
})
}
}
for _, metric := range ms {
metric.LabelKeys = []string{"container", "resource", "unit"}
}
return ms
}

func wrapVPAFunc(f func(*autoscaling.VerticalPodAutoscaler) *metric.Family) func(interface{}) *metric.Family {
return func(obj interface{}) *metric.Family {
vpa := obj.(*autoscaling.VerticalPodAutoscaler)
Expand Down
Loading

0 comments on commit 6d9eb11

Please sign in to comment.