Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

store: add metrics for VerticalPodAutoscaler objects #791

Merged

Conversation

milesbxf
Copy link
Contributor

@milesbxf milesbxf commented Jun 17, 2019

What this PR does / why we need it:

Adds support for metrics on VerticalPodAutoscaler objects. It was discussed in #781 whether this should be in the vertical-pod-autoscaler project, or a separate controller, but @brancz pointed out that the VPA is core Kubernetes, even if it isn't installed in every cluster.

I've based this off the v1beta2 of the VPA API - v1 has just been added to master, so can update to that once a new release of VPA has been cut.

One tricky thing I ran into is that I needed to use the custom VPA clientset, which requires a *rest.Config object to create. I've put forward the cleanest way of exposing this I can think of, but please let me know if an alternative is preferred.

Sample metric output

# HELP kube_vpa_labels Kubernetes labels converted to Prometheus labels.
# TYPE kube_vpa_labels gauge
kube_vpa_labels{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact"} 1
kube_vpa_labels{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query"} 1
kube_vpa_labels{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store"} 1
# HELP kube_vpa_update_mode Update mode of the VPA.
# TYPE kube_vpa_update_mode gauge
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",update_mode="Off"} 1
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",update_mode="Initial"} 0
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",update_mode="Recreate"} 0
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",update_mode="Auto"} 0
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",update_mode="Off"} 1
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",update_mode="Initial"} 0
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",update_mode="Recreate"} 0
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",update_mode="Auto"} 0
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",update_mode="Off"} 1
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",update_mode="Initial"} 0
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",update_mode="Recreate"} 0
kube_vpa_update_mode{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",update_mode="Auto"} 0
# HELP kube_vpa_container_resource_policy_min_cpu_cores Minimum CPU cores this VPA can set for containers matching the name.
# TYPE kube_vpa_container_resource_policy_min_cpu_cores gauge
kube_vpa_container_resource_policy_min_cpu_cores{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="*"} 1
kube_vpa_container_resource_policy_min_cpu_cores{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="*"} 0.01
kube_vpa_container_resource_policy_min_cpu_cores{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="*"} 1
# HELP kube_vpa_container_resource_policy_min_memory_bytes Minimum memory bytes this VPA can set for containers matching the name.
# TYPE kube_vpa_container_resource_policy_min_memory_bytes gauge
kube_vpa_container_resource_policy_min_memory_bytes{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="*"} 1.073741824e+10
kube_vpa_container_resource_policy_min_memory_bytes{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="*"} 1.073741824e+10
kube_vpa_container_resource_policy_min_memory_bytes{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="*"} 1.048576e+08
# HELP kube_vpa_container_resource_policy_max_cpu_cores Maximum CPU cores this VPA can set for containers matching the name.
# TYPE kube_vpa_container_resource_policy_max_cpu_cores gauge
kube_vpa_container_resource_policy_max_cpu_cores{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="*"} 7
kube_vpa_container_resource_policy_max_cpu_cores{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="*"} 4
kube_vpa_container_resource_policy_max_cpu_cores{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="*"} 7
# HELP kube_vpa_container_resource_policy_max_memory_bytes Maximum memory bytes this VPA can set for containers matching the name.
# TYPE kube_vpa_container_resource_policy_max_memory_bytes gauge
kube_vpa_container_resource_policy_max_memory_bytes{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="*"} 8.589934592e+10
kube_vpa_container_resource_policy_max_memory_bytes{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="*"} 8.589934592e+09
kube_vpa_container_resource_policy_max_memory_bytes{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="*"} 8.589934592e+10
# HELP kube_vpa_container_status_recommendation_lower_bound_cpu_cores Minimum CPU cores the container can use before the VPA updater evicts it.
# TYPE kube_vpa_container_status_recommendation_lower_bound_cpu_cores gauge
kube_vpa_container_status_recommendation_lower_bound_cpu_cores{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="thanos-compact"} 1
kube_vpa_container_status_recommendation_lower_bound_cpu_cores{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="thanos-query"} 0.025
kube_vpa_container_status_recommendation_lower_bound_cpu_cores{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="thanos-store"} 1
# HELP kube_vpa_container_status_recommendation_lower_bound_memory_bytes Minimum memory bytes the container can use before the VPA updater evicts it.
# TYPE kube_vpa_container_status_recommendation_lower_bound_memory_bytes gauge
kube_vpa_container_status_recommendation_lower_bound_memory_bytes{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="thanos-query"} 2.62144e+08
kube_vpa_container_status_recommendation_lower_bound_memory_bytes{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="thanos-store"} 1.073741824e+10
kube_vpa_container_status_recommendation_lower_bound_memory_bytes{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="thanos-compact"} 1.073741824e+10
# HELP kube_vpa_container_status_recommendation_upper_bound_cpu_cores Maximum CPU cores the container can use before the VPA updater evicts it.
# TYPE kube_vpa_container_status_recommendation_upper_bound_cpu_cores gauge
kube_vpa_container_status_recommendation_upper_bound_cpu_cores{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="thanos-compact"} 5.541
kube_vpa_container_status_recommendation_upper_bound_cpu_cores{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="thanos-query"} 0.058
kube_vpa_container_status_recommendation_upper_bound_cpu_cores{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="thanos-store"} 2.145
# HELP kube_vpa_container_status_recommendation_upper_bound_memory_bytes Maximum memory bytes the container can use before the VPA updater evicts it.
# TYPE kube_vpa_container_status_recommendation_upper_bound_memory_bytes gauge
kube_vpa_container_status_recommendation_upper_bound_memory_bytes{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="thanos-compact"} 6.1678944189e+10
kube_vpa_container_status_recommendation_upper_bound_memory_bytes{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="thanos-query"} 2.358755103e+09
kube_vpa_container_status_recommendation_upper_bound_memory_bytes{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="thanos-store"} 4.9252280142e+10
# HELP kube_vpa_container_status_recommendation_target_cpu_cores Target CPU cores the VPA recommends for the container.
# TYPE kube_vpa_container_status_recommendation_target_cpu_cores gauge
kube_vpa_container_status_recommendation_target_cpu_cores{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="thanos-compact"} 1
kube_vpa_container_status_recommendation_target_cpu_cores{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="thanos-query"} 0.025
kube_vpa_container_status_recommendation_target_cpu_cores{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="thanos-store"} 1
# HELP kube_vpa_container_status_recommendation_target_memory_bytes Target memory bytes the VPA recommends for the container.
# TYPE kube_vpa_container_status_recommendation_target_memory_bytes gauge
kube_vpa_container_status_recommendation_target_memory_bytes{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="thanos-compact"} 1.073741824e+10
kube_vpa_container_status_recommendation_target_memory_bytes{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="thanos-query"} 9.20733364e+08
kube_vpa_container_status_recommendation_target_memory_bytes{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="thanos-store"} 1.073741824e+10
# HELP kube_vpa_container_status_recommendation_uncapped_target_cpu_cores Target CPU cores the VPA recommends for the container ignoring bounds.
# TYPE kube_vpa_container_status_recommendation_uncapped_target_cpu_cores gauge
kube_vpa_container_status_recommendation_uncapped_target_cpu_cores{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="thanos-compact"} 0.763
kube_vpa_container_status_recommendation_uncapped_target_cpu_cores{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="thanos-query"} 0.025
kube_vpa_container_status_recommendation_uncapped_target_cpu_cores{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="thanos-store"} 0.323
# HELP kube_vpa_container_status_recommendation_uncapped_target_memory_bytes Target memory bytes the VPA recommends for the container ignoring bounds.
# TYPE kube_vpa_container_status_recommendation_uncapped_target_memory_bytes gauge
kube_vpa_container_status_recommendation_uncapped_target_memory_bytes{namespace="monitoring",vpa="thanos-compact",targetRef="apps/v1beta1/StatefulSet/thanos-compact",container_name="thanos-compact"} 9.616998332e+09
kube_vpa_container_status_recommendation_uncapped_target_memory_bytes{namespace="monitoring",vpa="thanos-query",targetRef="extensions/v1beta1/Deployment/thanos-query",container_name="thanos-query"} 9.20733364e+08
kube_vpa_container_status_recommendation_uncapped_target_memory_bytes{namespace="monitoring",vpa="thanos-store",targetRef="apps/v1beta1/StatefulSet/thanos-store",container_name="thanos-store"} 8.701517761e+09

Which issue(s) this PR fixes

Fixes #781

TODO

  • add unit tests
  • figure out how to make the verticalpodautoscalers collector not a default
  • add documentation on metrics
  • add example vpa.yaml for tests

@k8s-ci-robot
Copy link
Contributor

Welcome @milesbxf!

It looks like this is your first PR to kubernetes/kube-state-metrics 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/kube-state-metrics has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Jun 17, 2019
@milesbxf milesbxf force-pushed the vertical-pod-autoscaler-metrics branch 3 times, most recently from 4eac749 to ef2e5f4 Compare June 17, 2019 16:50
@brancz
Copy link
Member

brancz commented Jun 17, 2019

figure out how to make the verticalpodautoscalers collector not a default

There is an available and DefaultCollectors. For it not to be enabled by default, you want to only add it to the available, but not the default map.

@milesbxf
Copy link
Contributor Author

@brancz yep, I did that; however not having the verticalpodautoscalers in the DefaultCollectors causes an error when specifying it on the--collectors flag:

kube-state-metrics --port=8081 --telemetry-port=8082 --kubeconfig=$HOME/.kube/config --collectors verticalpodautoscalers
invalid argument "verticalpodautoscalers" for "--collectors" flag: collector "verticalpodautoscalers" does not exist
Usage of kube-state-metrics:
      --alsologtostderr                             log to standard error as well as files
      --apiserver string                            The URL of the apiserver to use as a master
      --collectors string                           Comma-separated list of collectors to be enabled. Defaults to "certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,limitranges,namespaces,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses"

Is this expected? Should I raise another issue?

@milesbxf milesbxf force-pushed the vertical-pod-autoscaler-metrics branch from ef2e5f4 to 0f4ed6e Compare June 18, 2019 11:19
@milesbxf
Copy link
Contributor Author

I've run into another obstacle - for the e2e (and I suspect other) tests to pass, they'll need minikube to have the vertical pod autoscaler component installed. Alternatively we could disable the check for kube_vpa* metrics, which feels like a nice compromise given we're not enabling this by default. What do you think?

@brancz
Copy link
Member

brancz commented Jun 18, 2019

I'm ok to not have them be part of e2e for now, especially as the metrics are marked as experimental. This would out of other things be a criteria for graduating them to stable metrics.

You're right about the error, that's a problem, and this code is wrong:

_, ok := DefaultCollectors[col]
if !ok {
return errors.Errorf("collector \"%s\" does not exist", col)
}
s[col] = struct{}{}

It shouldn't be checking on the DefaultCollectors but on the availableCollectors in the store package:

var availableStores = map[string]func(f *Builder) *metricsstore.MetricsStore{

Feel free to introduce a function or export or move code as needed to make this work. Important is that the model of available collectors vs default collectors ends up the way we initially expected 🙂 .

@milesbxf
Copy link
Contributor Author

@brancz cool, I'll exclude 👍

I've fixed the issue with default and available collectors in a separate PR here: #793

main.go Outdated Show resolved Hide resolved
)

var (
descVerticalPodAutoscalerLabelsName = "kube_vpa_labels"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write out vpa, this is done for all metrics in kube-state-metrics (and those that are not are targeted to be changed for a breaking release)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear - you mean rename kube_vpa -> kube_verticalpodautoscaler?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

min := c.MinAllowed
if cpu, ok := min[v1.ResourceCPU]; ok {
ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be container, same for all usages below

ms = append(ms, &metric.Metric{
LabelKeys: []string{"container_name"},
LabelValues: []string{c.ContainerName},
Value: float64(cpu.MilliValue()) / 1000,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the resource type can do the conversion internally, I don't think we have to do the math here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I take the float64 conversion off I get:

cannot use val.MilliValue() / 1000 (type int64) as type float64 in field value

}),
},
{
Name: "kube_vpa_container_status_recommendation_lower_bound_memory_bytes",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for resource requests/limits on containers/pods we made this generic, and deprecated the non generic metrics, we should have just the generic one here

}),
},
{
Name: "kube_vpa_container_status_recommendation_target_cpu_cores",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as lower bound, this should be generic for resource types

}),
},
{
Name: "kube_vpa_container_status_recommendation_uncapped_target_cpu_cores",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

vpa := obj.(*autoscaling.VerticalPodAutoscaler)

metricFamily := f(vpa)
targetRef := fmt.Sprintf("%s/%s/%s", vpa.Spec.TargetRef.APIVersion, vpa.Spec.TargetRef.Kind, vpa.Spec.TargetRef.Name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not have this be separate labels?

}

func createVPAListWatchFunc(kubeCfg *rest.Config) func(kubeClient clientset.Interface, ns string) cache.ListerWatcher {
vpaClient, err := vpaclientset.NewForConfig(kubeCfg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this creation should be on the same level as we create the kubeclient, so we can actually properly handle the resulting error


func TestVPAStore(t *testing.T) {

const metadata = `
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the metadata should be tested

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've put in the metadata, but I'm not sure where to reference it in the tests - in most of the other collectors we just define it as a const but don't actually do anything with it

main.go Outdated
}
klog.Infof("Running with Kubernetes cluster version: v%s.%s. git version: %s. git tree state: %s. commit: %s. platform: %s",
v.Major, v.Minor, v.GitVersion, v.GitTreeState, v.GitCommit, v.Platform)
klog.Infof("Communication with server successful")

return kubeClient, nil
return kubeClient, config, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create and return both the kubeclient and vpaclient (if enabled) here I would say

@milesbxf milesbxf force-pushed the vertical-pod-autoscaler-metrics branch from 3e8ef4c to 6d9eb11 Compare June 18, 2019 16:30
@milesbxf
Copy link
Contributor Author

@brancz @tariq1890 I think I've addressed all your review comments 👍

@tariq1890
Copy link
Contributor

Haven't had an in-depth look, but I think
i) you need to update this
ii) (I believe) you shouldn't be checking for vpa metrics in the e2e tests since it's disabled by default.

@milesbxf
Copy link
Contributor Author

Hooray, finally got CI passing 🎉

@tariq1890 the verticalpodautoscaler collector (now) isn't enabled by default, so won't show up in the CLI args

As for e2e, there doesn't seem to be any check as to whether the resource is enabled or not (though perhaps that would be a smarter approach than I've got here) - it simply lists out files under the ./internal/store directory with this oneliner:

resources=$(find internal/store/ -maxdepth 1 -name "*.go" -not -name "*_test.go" -not -name "builder.go" -not -name "testutils.go" -not -name "utils.go" -print0 | xargs -0 -n1 basename | awk -F. '{print $1}'| grep -v "$EXCLUDED_RESOURCE_REGEX")

{
Name: "kube_verticalpodautoscaler_update_mode",
Type: metric.Gauge,
Help: "Update mode of the VPA.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a preference for vertical pod autoscaler over vpa in the metrics help text.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@tariq1890
Copy link
Contributor

@milesbxf Thanks for your patience. Just one more comment needs addressing and it's an okay from me. Deferring to @brancz for final review and merge.

@tariq1890
Copy link
Contributor

tariq1890 commented Jun 19, 2019

Also, need to squash commit history.

@milesbxf milesbxf force-pushed the vertical-pod-autoscaler-metrics branch from 5b1a7e5 to ef90e80 Compare June 19, 2019 16:22
@milesbxf
Copy link
Contributor Author

Squashed, so it's ready for @brancz to look at 🙂

@tariq1890
Copy link
Contributor

Can this be merged @brancz?

@brancz
Copy link
Member

brancz commented Jun 20, 2019

Still reviewing.

Copy link
Member

@brancz brancz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going in the right direction, some naming scheme and docs things. Overall the approach looks sane and in line with the rest of kube-state-metrics. Thanks a lot for taking care of this!

| kube_verticalpodautoscaler_container_resource_policy_max | Gauge | `container`=&lt;container name&gt; <br> `namespace`=&lt;namespace&gt; <br> `resource`=&lt;cpu | memory&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `unit`=&lt;core | byte&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
| kube_verticalpodautoscaler_container_resource_policy_min | Gauge | `container`=&lt;container name&gt; <br> `namespace`=&lt;namespace&gt; <br> `resource`=&lt;cpu | memory&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `unit`=&lt;core | byte&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
| kube_verticalpodautoscaler_container_resource_policy_min | Gauge | `container`=&lt;container name&gt; <br> `namespace`=&lt;namespace&gt; <br> `resource`=&lt;cpu | memory&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `unit`=&lt;core | byte&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
| kube_verticalpodautoscaler_container_status_recommendation_lower_bound | Gauge | `container`=&lt;container name&gt; <br> `namespace`=&lt;namespace&gt; <br> `resource`=&lt;cpu | memory&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `unit`=&lt;core | byte&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all kube_verticalpodautoscaler_container_status_.* metric docs are duplicate


| Metric name | Metric type | Labels/tags | Status |
| -------------------------------- | ----------- | ------------------------------------------------------------- | ------ |
| kube_verticalpodautoscaler_container_resource_policy_max | Gauge | `container`=&lt;container name&gt; <br> `namespace`=&lt;namespace&gt; <br> `resource`=&lt;cpu | memory&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `unit`=&lt;core | byte&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all kube_verticalpodautoscaler_container_resource_policy.* metrics are duplicate

| kube_verticalpodautoscaler_container_status_recommendation_upper_bound | Gauge | `container`=&lt;container name&gt; <br> `namespace`=&lt;namespace&gt; <br> `resource`=&lt;cpu | memory&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `unit`=&lt;core | byte&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
| kube_verticalpodautoscaler_container_status_recommendation_upper_bound | Gauge | `container`=&lt;container name&gt; <br> `namespace`=&lt;namespace&gt; <br> `resource`=&lt;cpu | memory&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `unit`=&lt;core | byte&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
| kube_verticalpodautoscaler_labels | Gauge | `label_app`=&lt;foo&gt; <br> `namespace`=&lt;namespace&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
| kube_verticalpodautoscaler_update_mode | Gauge | `namespace`=&lt;namespace&gt; <br> `target_api_version`=&lt;api version&gt; <br> `target_kind`=&lt;target kind&gt; <br> `target_name`=&lt;target name&gt; <br> `update_mode`=&lt;foo&gt; <br> `verticalpodautoscaler`=&lt;vertical pod autoscaler name&gt; | EXPERIMENTAL |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this metric is documented 4 times

}),
},
{
Name: "kube_verticalpodautoscaler_container_resource_policy_min",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should stay as close as possible to the original naming, so this should be kube_verticalpodautoscaler_resourcepolicy_containerpolicies.

}),
},
{
Name: "kube_verticalpodautoscaler_container_resource_policy_max",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

naming same scheme as kube_verticalpodautoscaler_container_resource_policy_min

}),
},
{
Name: "kube_verticalpodautoscaler_container_status_recommendation_lower_bound",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

naming same scheme as kube_verticalpodautoscaler_container_resource_policy_min, although unfortunately due to the API definition, this is gonna end up a bit weird, but I'd still prefer to stick to systematic naming, so something like: kube_verticalpodautoscaler_status_recommendation_containerrecommendations_lower_bound

LabelValues: []string{containerName, sanitizeLabelName(string(resourceName)), string(constant.UnitCore)},
Value: float64(val.MilliValue()) / 1000,
})
case v1.ResourceStorage:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it really necessary to whitelist each type here? can't we just normalize to base units in any case and put the resource name in the unit label?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brancz I'm a little conflicted about this - I'm actually tempted to remove the Storage cases (if I'm honest, I copied and pasted this from the kube_pod_container_resource_requests).

At the moment the VPA only operates on CPU and memory, though there's a discussion about adding ephemeral storage (kubernetes/autoscaler#1751). Those are the only metrics exposed by the Metrics Server AFAIK, so it's unlikely we'd need to whitelist every type of resource.

I'm also not sure how we'd generically normalize to base units - I'd consider the base unit of CPU to be a core, and the resource.Quantity only provides an int Value for that 😢

Personally I'm in favour of keeping this consistent with how kube_pod_container_resource_requests works, though I don't feel strongly about this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair, I was just thinking if we can find a default case similar to kube_pod_container_resource_requests. But I'm also happy to just add it when we're actually at a point where this is a reality.

@milesbxf milesbxf force-pushed the vertical-pod-autoscaler-metrics branch from ef90e80 to 67ef5ec Compare June 20, 2019 11:24
@milesbxf
Copy link
Contributor Author

Going in the right direction, some naming scheme and docs things. Overall the approach looks sane and in line with the rest of kube-state-metrics. Thanks a lot for taking care of this!

Thanks. I've updated the metric names to match the api spec path as closely as possible 👍

@brancz
Copy link
Member

brancz commented Jun 20, 2019

Wonderful. Thanks for bearding with me :)

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 20, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: brancz, milesbxf

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 20, 2019
@k8s-ci-robot k8s-ci-robot merged commit 0ffcc30 into kubernetes:master Jun 20, 2019
@milesbxf milesbxf deleted the vertical-pod-autoscaler-metrics branch June 20, 2019 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add metrics about Vertical Pod Autoscaler recommendations
4 participants