mirror of
https://github.com/zalando-incubator/kube-metrics-adapter.git
synced 2024-12-22 11:06:04 +00:00
Merge pull request #101 from zalando-incubator/update-to-v2beta2
Only support autoscaling/v2beta2
This commit is contained in:
commit
9e211b181a
@ -1,7 +1,4 @@
|
||||
run:
|
||||
skip-files:
|
||||
- "pkg/provider/generated.conversion.go"
|
||||
- "pkg/provider/conversion.go"
|
||||
linters-settings:
|
||||
golint:
|
||||
min-confidence: 0.9
|
||||
|
152
README.md
152
README.md
@ -17,7 +17,7 @@ Here's an example of a `HorizontalPodAutoscaler` resource configured to get
|
||||
`requests-per-second` metrics from each pod of the deployment `myapp`.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2beta2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -36,8 +36,11 @@ spec:
|
||||
metrics:
|
||||
- type: Pods
|
||||
pods:
|
||||
metricName: requests-per-second
|
||||
targetAverageValue: 1k
|
||||
metric:
|
||||
name: requests-per-second
|
||||
target:
|
||||
averageValue: 1k
|
||||
type: AverageValue
|
||||
```
|
||||
|
||||
The `metric-config.*` annotations are used by the `kube-metrics-adapter` to
|
||||
@ -51,10 +54,10 @@ policy](https://kubernetes.io/docs/setup/release/version-skew-policy/) offered
|
||||
for Kubernetes, this project aims to support the latest three minor releases of
|
||||
Kubernetes.
|
||||
|
||||
Currently the default supported API is `autoscaling/v2beta1`. However we aim to
|
||||
move to `autoscaling/v2beta2` (available since `v1.12`) in the near future as
|
||||
this adds a lot of improvements over `v2beta1`. The move to `v2beta2` will most
|
||||
likely happen as soon as [GKE adds support for it](https://issuetracker.google.com/issues/135624588).
|
||||
The default supported API is `autoscaling/v2beta2` (available since `v1.12`).
|
||||
This API MUST be available in the cluster which is the default. However for
|
||||
GKE, this requires GKE v1.15.7 according to this [GKE
|
||||
Issue](https://issuetracker.google.com/issues/135624588).
|
||||
|
||||
## Building
|
||||
|
||||
@ -88,7 +91,7 @@ Currently only `json-path` collection is supported.
|
||||
|
||||
| Metric | Description | Type | K8s Versions |
|
||||
| ------------ | -------------- | ------- | -- |
|
||||
| *custom* | No predefined metrics. Metrics are generated from user defined queries. | Pods | `>=1.10` |
|
||||
| *custom* | No predefined metrics. Metrics are generated from user defined queries. | Pods | `>=1.12` |
|
||||
|
||||
### Example
|
||||
|
||||
@ -96,7 +99,7 @@ This is an example of using the pod collector to collect metrics from a json
|
||||
metrics endpoint of each pod matched by the HPA.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2beta2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -117,8 +120,11 @@ spec:
|
||||
metrics:
|
||||
- type: Pods
|
||||
pods:
|
||||
metricName: requests-per-second
|
||||
targetAverageValue: 1k
|
||||
metric:
|
||||
name: requests-per-second
|
||||
target:
|
||||
averageValue: 1k
|
||||
type: AverageValue
|
||||
```
|
||||
|
||||
The pod collector is configured through the annotations which specify the
|
||||
@ -174,8 +180,8 @@ the trade-offs between the two approaches.
|
||||
|
||||
| Metric | Description | Type | Kind | K8s Versions |
|
||||
| ------------ | -------------- | ------- | -- | -- |
|
||||
| `prometheus-query` | Generic metric which requires a user defined query. | External | | `>=1.10` |
|
||||
| *custom* | No predefined metrics. Metrics are generated from user defined queries. | Object | *any* | `>=1.10` |
|
||||
| `prometheus-query` | Generic metric which requires a user defined query. | External | | `>=1.12` |
|
||||
| *custom* | No predefined metrics. Metrics are generated from user defined queries. | Object | *any* | `>=1.12` |
|
||||
|
||||
### Example: External Metric
|
||||
|
||||
@ -188,7 +194,7 @@ the `matchLabels` of the metric definition. This allows having multiple
|
||||
prometheus queries associated with a single HPA.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2beta2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -211,11 +217,14 @@ spec:
|
||||
metrics:
|
||||
- type: External
|
||||
external:
|
||||
metricName: prometheus-query
|
||||
metricSelector:
|
||||
matchLabels:
|
||||
query-name: processed-events-per-second
|
||||
targetAverageValue: 10
|
||||
metric:
|
||||
name: prometheus-query
|
||||
selector:
|
||||
matchLabels:
|
||||
query-name: processed-events-per-second
|
||||
target:
|
||||
type: AverageValue
|
||||
averageValue: "10"
|
||||
```
|
||||
|
||||
### Example: Object Metric [DEPRECATED]
|
||||
@ -282,7 +291,7 @@ box so users don't have to define those manually.
|
||||
|
||||
| Metric | Description | Type | Kind | K8s Versions |
|
||||
| ----------- | -------------- | ------ | ---- | ---- |
|
||||
| `requests-per-second` | Scale based on requests per second for a certain ingress. | Object | `Ingress` | `>=1.14` (can work with `>=1.10`) |
|
||||
| `requests-per-second` | Scale based on requests per second for a certain ingress. | Object | `Ingress` | `>=1.14` |
|
||||
|
||||
### Example
|
||||
|
||||
@ -290,7 +299,7 @@ This is an example of an HPA that will scale based on `requests-per-second` for
|
||||
an ingress called `myapp`.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2beta2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -304,38 +313,28 @@ spec:
|
||||
metrics:
|
||||
- type: Object
|
||||
object:
|
||||
metricName: requests-per-second
|
||||
target:
|
||||
describedObject:
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
name: myapp
|
||||
averageValue: 10 # Only works with Kubernetes >=1.14
|
||||
# for Kubernetes <1.14 you can use `targetValue` instead:
|
||||
targetValue: 10 # this must be set, but has no effect if `averageValue` is defined.
|
||||
# Otherwise it will be treated as targetAverageValue
|
||||
metric:
|
||||
name: requests-per-second
|
||||
target:
|
||||
averageValue: "10"
|
||||
type: AverageValue
|
||||
```
|
||||
|
||||
### Metric weighting based on backend
|
||||
|
||||
Skipper supports sending traffic to different backend based on annotations present on the
|
||||
`Ingress` object. When the metric name is specified without a backend as `requests-per-second`
|
||||
then the number of replicas will be calculated based on the full traffic served by that ingress.
|
||||
If however only the traffic being routed to a specific backend should be used then the
|
||||
backend name can be specified as a metric name like `requests-per-second,backend1` which would
|
||||
return the requests-per-second being sent to the `backend1`. The ingress annotation where
|
||||
the backend weights can be obtained can be specified through the flag `--skipper-backends-annotation`.
|
||||
|
||||
|
||||
**Note:** For Kubernetes `<v1.14` the HPA does not support `averageValue` for
|
||||
metrics of type `Object`. In case of requests per second it does not make sense
|
||||
to scale on a summed value because you can not make the total requests per
|
||||
second go down by adding more pods. For this reason the skipper collector will
|
||||
automatically treat the value you define in `targetValue` as an average per pod
|
||||
instead of a total sum.
|
||||
|
||||
**ONLY use `targetValue` if you are on Kubernetes
|
||||
`<1.14`, it is not as percise as using `averageValue` and will not be supported
|
||||
after Kubernetes `v1.16` is released according to the [support policy](https://kubernetes.io/docs/setup/release/version-skew-policy/).**
|
||||
Skipper supports sending traffic to different backend based on annotations
|
||||
present on the `Ingress` object. When the metric name is specified without a
|
||||
backend as `requests-per-second` then the number of replicas will be calculated
|
||||
based on the full traffic served by that ingress. If however only the traffic
|
||||
being routed to a specific backend should be used then the backend name can be
|
||||
specified as a metric name like `requests-per-second,backend1` which would
|
||||
return the requests-per-second being sent to the `backend1`. The ingress
|
||||
annotation where the backend weights can be obtained can be specified through
|
||||
the flag `--skipper-backends-annotation`.
|
||||
|
||||
## InfluxDB collector
|
||||
|
||||
@ -360,10 +359,10 @@ A matching `query-name` label must be defined in the `matchLabels` of the metric
|
||||
This allows having multiple flux queries associated with a single HPA.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2beta2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: my-hpa
|
||||
name: myapp-hpa
|
||||
annotations:
|
||||
# These annotations are optional.
|
||||
# If specified, then they are used for setting up the InfluxDB client properly,
|
||||
@ -395,11 +394,14 @@ spec:
|
||||
metrics:
|
||||
- type: External
|
||||
external:
|
||||
metricName: flux-query
|
||||
metricSelector:
|
||||
matchLabels:
|
||||
query-name: queue_depth
|
||||
targetValue: 1
|
||||
metric:
|
||||
name: flux-query
|
||||
selector:
|
||||
matchLabels:
|
||||
query-name: queue_depth
|
||||
target:
|
||||
type: Value
|
||||
value: "1"
|
||||
```
|
||||
|
||||
## AWS collector
|
||||
@ -435,7 +437,7 @@ PolicyDocument:
|
||||
|
||||
| Metric | Description | Type | K8s Versions |
|
||||
| ------------ | ------- | -- | -- |
|
||||
| `sqs-queue-length` | Scale based on SQS queue length | External | `>=1.10` |
|
||||
| `sqs-queue-length` | Scale based on SQS queue length | External | `>=1.12` |
|
||||
|
||||
### Example
|
||||
|
||||
@ -443,7 +445,7 @@ This is an example of an HPA that will scale based on the length of an SQS
|
||||
queue.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2beta2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -457,12 +459,15 @@ spec:
|
||||
metrics:
|
||||
- type: External
|
||||
external:
|
||||
metricName: sqs-queue-length
|
||||
metricSelector:
|
||||
matchLabels:
|
||||
queue-name: foobar
|
||||
region: eu-central-1
|
||||
targetAverageValue: 30
|
||||
metric:
|
||||
name: sqs-queue-length
|
||||
selector:
|
||||
matchLabels:
|
||||
queue-name: foobar
|
||||
region: eu-central-1
|
||||
target:
|
||||
averageValue: "30"
|
||||
type: AverageValue
|
||||
```
|
||||
|
||||
The `matchLabels` are used by `kube-metrics-adapter` to configure a collector
|
||||
@ -483,7 +488,7 @@ The ZMON collector allows scaling based on external metrics exposed by
|
||||
|
||||
| Metric | Description | Type | K8s Versions |
|
||||
| ------------ | ------- | -- | -- |
|
||||
| `zmon-check` | Scale based on any ZMON check results | External | `>=1.10` |
|
||||
| `zmon-check` | Scale based on any ZMON check results | External | `>=1.12` |
|
||||
|
||||
### Example
|
||||
|
||||
@ -491,7 +496,7 @@ This is an example of an HPA that will scale based on the specified value
|
||||
exposed by a ZMON check with id `1234`.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2beta2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -509,15 +514,18 @@ spec:
|
||||
metrics:
|
||||
- type: External
|
||||
external:
|
||||
metricName: zmon-check
|
||||
metricSelector:
|
||||
matchLabels:
|
||||
check-id: "1234" # the ZMON check to query for metrics
|
||||
key: "custom.value"
|
||||
tag-application: my-custom-app
|
||||
aggregators: avg # comma separated list of aggregation functions, default: last
|
||||
duration: 5m # default: 10m
|
||||
targetAverageValue: 30
|
||||
metric:
|
||||
name: zmon-check
|
||||
selector:
|
||||
matchLabels:
|
||||
check-id: "1234" # the ZMON check to query for metrics
|
||||
key: "custom.value"
|
||||
tag-application: my-custom-app
|
||||
aggregators: avg # comma separated list of aggregation functions, default: last
|
||||
duration: 5m # default: 10m
|
||||
target:
|
||||
averageValue: "30"
|
||||
type: AverageValue
|
||||
```
|
||||
|
||||
The `check-id` specifies the ZMON check to query for the metrics. `key`
|
||||
|
@ -1,4 +1,4 @@
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2beta2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: custom-metrics-consumer
|
||||
@ -25,25 +25,36 @@ spec:
|
||||
# - type: Resource
|
||||
# resource:
|
||||
# name: cpu
|
||||
# targetAverageUtilization: 50
|
||||
# current:
|
||||
# averageUtilization: 50
|
||||
|
||||
- type: Pods
|
||||
pods:
|
||||
metricName: queue-length
|
||||
targetAverageValue: 1k
|
||||
metric:
|
||||
name: queue-length
|
||||
target:
|
||||
averageValue: 1k
|
||||
type: AverageValue
|
||||
|
||||
- type: Object
|
||||
object:
|
||||
metricName: requests-per-second
|
||||
target:
|
||||
describedObject:
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
name: custom-metrics-consumer
|
||||
averageValue: 10
|
||||
targetValue: 10 # this must be set, but has no effect if `averageValue` is defined.
|
||||
metric:
|
||||
name: requests-per-second
|
||||
target:
|
||||
averageValue: "10"
|
||||
type: AverageValue
|
||||
- type: External
|
||||
external:
|
||||
metricName: sqs-queue-length
|
||||
metricSelector:
|
||||
matchLabels:
|
||||
queue-name: foobar
|
||||
region: eu-central-1
|
||||
targetAverageValue: 30
|
||||
metric:
|
||||
name: sqs-queue-length
|
||||
selector:
|
||||
matchLabels:
|
||||
queue-name: foobar
|
||||
region: eu-central-1
|
||||
target:
|
||||
averageValue: "30"
|
||||
type: AverageValue
|
||||
|
@ -1,247 +0,0 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta2"
|
||||
core "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
)
|
||||
|
||||
// from: https://github.com/kubernetes/kubernetes/blob/v1.14.4/pkg/apis/autoscaling/v2beta1/conversion.go
|
||||
|
||||
func Convert_autoscaling_MetricTarget_To_v2beta1_CrossVersionObjectReference(in *autoscaling.MetricTarget, out *autoscalingv2beta1.CrossVersionObjectReference, s conversion.Scope) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_CrossVersionObjectReference_To_autoscaling_MetricTarget(in *autoscalingv2beta1.CrossVersionObjectReference, out *autoscaling.MetricTarget, s conversion.Scope) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_ResourceMetricStatus_To_autoscaling_ResourceMetricStatus(in *autoscalingv2beta1.ResourceMetricStatus, out *autoscaling.ResourceMetricStatus, s conversion.Scope) error {
|
||||
out.Name = core.ResourceName(in.Name)
|
||||
utilization := in.CurrentAverageUtilization
|
||||
averageValue := in.CurrentAverageValue
|
||||
out.Current = autoscaling.MetricValueStatus{
|
||||
AverageValue: &averageValue,
|
||||
AverageUtilization: utilization,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_autoscaling_ResourceMetricStatus_To_v2beta1_ResourceMetricStatus(in *autoscaling.ResourceMetricStatus, out *autoscalingv2beta1.ResourceMetricStatus, s conversion.Scope) error {
|
||||
out.Name = v1.ResourceName(in.Name)
|
||||
out.CurrentAverageUtilization = in.Current.AverageUtilization
|
||||
if in.Current.AverageValue != nil {
|
||||
out.CurrentAverageValue = *in.Current.AverageValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_ResourceMetricSource_To_autoscaling_ResourceMetricSource(in *autoscalingv2beta1.ResourceMetricSource, out *autoscaling.ResourceMetricSource, s conversion.Scope) error {
|
||||
out.Name = core.ResourceName(in.Name)
|
||||
utilization := in.TargetAverageUtilization
|
||||
averageValue := in.TargetAverageValue
|
||||
|
||||
var metricType autoscaling.MetricTargetType
|
||||
if utilization == nil {
|
||||
metricType = autoscaling.AverageValueMetricType
|
||||
} else {
|
||||
metricType = autoscaling.UtilizationMetricType
|
||||
}
|
||||
out.Target = autoscaling.MetricTarget{
|
||||
Type: metricType,
|
||||
AverageValue: averageValue,
|
||||
AverageUtilization: utilization,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_autoscaling_ResourceMetricSource_To_v2beta1_ResourceMetricSource(in *autoscaling.ResourceMetricSource, out *autoscalingv2beta1.ResourceMetricSource, s conversion.Scope) error {
|
||||
out.Name = v1.ResourceName(in.Name)
|
||||
out.TargetAverageUtilization = in.Target.AverageUtilization
|
||||
out.TargetAverageValue = in.Target.AverageValue
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_autoscaling_ExternalMetricSource_To_v2beta1_ExternalMetricSource(in *autoscaling.ExternalMetricSource, out *autoscalingv2beta1.ExternalMetricSource, s conversion.Scope) error {
|
||||
out.MetricName = in.Metric.Name
|
||||
out.TargetValue = in.Target.Value
|
||||
out.TargetAverageValue = in.Target.AverageValue
|
||||
out.MetricSelector = in.Metric.Selector
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_ExternalMetricSource_To_autoscaling_ExternalMetricSource(in *autoscalingv2beta1.ExternalMetricSource, out *autoscaling.ExternalMetricSource, s conversion.Scope) error {
|
||||
value := in.TargetValue
|
||||
averageValue := in.TargetAverageValue
|
||||
|
||||
var metricType autoscaling.MetricTargetType
|
||||
if value == nil {
|
||||
metricType = autoscaling.AverageValueMetricType
|
||||
} else {
|
||||
metricType = autoscaling.ValueMetricType
|
||||
}
|
||||
|
||||
out.Target = autoscaling.MetricTarget{
|
||||
Type: metricType,
|
||||
Value: value,
|
||||
AverageValue: averageValue,
|
||||
}
|
||||
|
||||
out.Metric = autoscaling.MetricIdentifier{
|
||||
Name: in.MetricName,
|
||||
Selector: in.MetricSelector,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_autoscaling_ObjectMetricSource_To_v2beta1_ObjectMetricSource(in *autoscaling.ObjectMetricSource, out *autoscalingv2beta1.ObjectMetricSource, s conversion.Scope) error {
|
||||
if in.Target.Value != nil {
|
||||
out.TargetValue = *in.Target.Value
|
||||
}
|
||||
out.AverageValue = in.Target.AverageValue
|
||||
|
||||
out.Target = autoscalingv2beta1.CrossVersionObjectReference{
|
||||
Kind: in.DescribedObject.Kind,
|
||||
Name: in.DescribedObject.Name,
|
||||
APIVersion: in.DescribedObject.APIVersion,
|
||||
}
|
||||
out.MetricName = in.Metric.Name
|
||||
out.Selector = in.Metric.Selector
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_ObjectMetricSource_To_autoscaling_ObjectMetricSource(in *autoscalingv2beta1.ObjectMetricSource, out *autoscaling.ObjectMetricSource, s conversion.Scope) error {
|
||||
var metricType autoscaling.MetricTargetType
|
||||
if in.AverageValue == nil {
|
||||
metricType = autoscaling.ValueMetricType
|
||||
} else {
|
||||
metricType = autoscaling.AverageValueMetricType
|
||||
}
|
||||
out.Target = autoscaling.MetricTarget{
|
||||
Type: metricType,
|
||||
Value: &in.TargetValue,
|
||||
AverageValue: in.AverageValue,
|
||||
}
|
||||
out.DescribedObject = autoscaling.CrossVersionObjectReference{
|
||||
Kind: in.Target.Kind,
|
||||
Name: in.Target.Name,
|
||||
APIVersion: in.Target.APIVersion,
|
||||
}
|
||||
out.Metric = autoscaling.MetricIdentifier{
|
||||
Name: in.MetricName,
|
||||
Selector: in.Selector,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_autoscaling_PodsMetricSource_To_v2beta1_PodsMetricSource(in *autoscaling.PodsMetricSource, out *autoscalingv2beta1.PodsMetricSource, s conversion.Scope) error {
|
||||
if in.Target.AverageValue != nil {
|
||||
targetAverageValue := *in.Target.AverageValue
|
||||
out.TargetAverageValue = targetAverageValue
|
||||
}
|
||||
|
||||
out.MetricName = in.Metric.Name
|
||||
out.Selector = in.Metric.Selector
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_PodsMetricSource_To_autoscaling_PodsMetricSource(in *autoscalingv2beta1.PodsMetricSource, out *autoscaling.PodsMetricSource, s conversion.Scope) error {
|
||||
targetAverageValue := &in.TargetAverageValue
|
||||
var metricType autoscaling.MetricTargetType
|
||||
metricType = autoscaling.AverageValueMetricType
|
||||
|
||||
out.Target = autoscaling.MetricTarget{
|
||||
Type: metricType,
|
||||
AverageValue: targetAverageValue,
|
||||
}
|
||||
out.Metric = autoscaling.MetricIdentifier{
|
||||
Name: in.MetricName,
|
||||
Selector: in.Selector,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_autoscaling_ExternalMetricStatus_To_v2beta1_ExternalMetricStatus(in *autoscaling.ExternalMetricStatus, out *autoscalingv2beta1.ExternalMetricStatus, s conversion.Scope) error {
|
||||
if &in.Current.AverageValue != nil {
|
||||
out.CurrentAverageValue = in.Current.AverageValue
|
||||
}
|
||||
out.MetricName = in.Metric.Name
|
||||
if in.Current.Value != nil {
|
||||
out.CurrentValue = *in.Current.Value
|
||||
}
|
||||
out.MetricSelector = in.Metric.Selector
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_ExternalMetricStatus_To_autoscaling_ExternalMetricStatus(in *autoscalingv2beta1.ExternalMetricStatus, out *autoscaling.ExternalMetricStatus, s conversion.Scope) error {
|
||||
value := in.CurrentValue
|
||||
averageValue := in.CurrentAverageValue
|
||||
out.Current = autoscaling.MetricValueStatus{
|
||||
Value: &value,
|
||||
AverageValue: averageValue,
|
||||
}
|
||||
out.Metric = autoscaling.MetricIdentifier{
|
||||
Name: in.MetricName,
|
||||
Selector: in.MetricSelector,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_autoscaling_ObjectMetricStatus_To_v2beta1_ObjectMetricStatus(in *autoscaling.ObjectMetricStatus, out *autoscalingv2beta1.ObjectMetricStatus, s conversion.Scope) error {
|
||||
if in.Current.Value != nil {
|
||||
out.CurrentValue = *in.Current.Value
|
||||
}
|
||||
out.Target = autoscalingv2beta1.CrossVersionObjectReference{
|
||||
Kind: in.DescribedObject.Kind,
|
||||
Name: in.DescribedObject.Name,
|
||||
APIVersion: in.DescribedObject.APIVersion,
|
||||
}
|
||||
out.MetricName = in.Metric.Name
|
||||
out.Selector = in.Metric.Selector
|
||||
if in.Current.AverageValue != nil {
|
||||
currentAverageValue := *in.Current.AverageValue
|
||||
out.AverageValue = ¤tAverageValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_ObjectMetricStatus_To_autoscaling_ObjectMetricStatus(in *autoscalingv2beta1.ObjectMetricStatus, out *autoscaling.ObjectMetricStatus, s conversion.Scope) error {
|
||||
out.Current = autoscaling.MetricValueStatus{
|
||||
Value: &in.CurrentValue,
|
||||
AverageValue: in.AverageValue,
|
||||
}
|
||||
out.DescribedObject = autoscaling.CrossVersionObjectReference{
|
||||
Kind: in.Target.Kind,
|
||||
Name: in.Target.Name,
|
||||
APIVersion: in.Target.APIVersion,
|
||||
}
|
||||
out.Metric = autoscaling.MetricIdentifier{
|
||||
Name: in.MetricName,
|
||||
Selector: in.Selector,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_autoscaling_PodsMetricStatus_To_v2beta1_PodsMetricStatus(in *autoscaling.PodsMetricStatus, out *autoscalingv2beta1.PodsMetricStatus, s conversion.Scope) error {
|
||||
if in.Current.AverageValue != nil {
|
||||
out.CurrentAverageValue = *in.Current.AverageValue
|
||||
}
|
||||
out.MetricName = in.Metric.Name
|
||||
out.Selector = in.Metric.Selector
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v2beta1_PodsMetricStatus_To_autoscaling_PodsMetricStatus(in *autoscalingv2beta1.PodsMetricStatus, out *autoscaling.PodsMetricStatus, s conversion.Scope) error {
|
||||
out.Current = autoscaling.MetricValueStatus{
|
||||
AverageValue: &in.CurrentAverageValue,
|
||||
}
|
||||
out.Metric = autoscaling.MetricIdentifier{
|
||||
Name: in.MetricName,
|
||||
Selector: in.Selector,
|
||||
}
|
||||
return nil
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -116,7 +116,7 @@ func (p *HPAProvider) Run(ctx context.Context) {
|
||||
func (p *HPAProvider) updateHPAs() error {
|
||||
p.logger.Info("Looking for HPAs")
|
||||
|
||||
hpas, err := p.client.AutoscalingV2beta1().HorizontalPodAutoscalers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
hpas, err := p.client.AutoscalingV2beta2().HorizontalPodAutoscalers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -125,15 +125,7 @@ func (p *HPAProvider) updateHPAs() error {
|
||||
|
||||
newHPAs := 0
|
||||
|
||||
for _, hpav1 := range hpas.Items {
|
||||
hpav1 := hpav1
|
||||
hpa := autoscalingv2.HorizontalPodAutoscaler{}
|
||||
err := Convert_v2beta1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutoscaler(&hpav1, &hpa, nil)
|
||||
if err != nil {
|
||||
p.logger.Errorf("Failed to convert HPA to v2beta2: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, hpa := range hpas.Items {
|
||||
resourceRef := resourceReference{
|
||||
Name: hpa.Name,
|
||||
Namespace: hpa.Namespace,
|
||||
|
@ -7,8 +7,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zalando-incubator/kube-metrics-adapter/pkg/collector"
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
|
||||
autoscaling "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
@ -16,7 +15,7 @@ import (
|
||||
|
||||
type mockCollectorPlugin struct{}
|
||||
|
||||
func (m mockCollectorPlugin) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscaler, config *collector.MetricConfig, interval time.Duration) (collector.Collector, error) {
|
||||
func (m mockCollectorPlugin) NewCollector(hpa *autoscaling.HorizontalPodAutoscaler, config *collector.MetricConfig, interval time.Duration) (collector.Collector, error) {
|
||||
return mockCollector{}, nil
|
||||
}
|
||||
|
||||
@ -33,7 +32,7 @@ func (c mockCollector) Interval() time.Duration {
|
||||
func TestUpdateHPAs(t *testing.T) {
|
||||
value := resource.MustParse("1k")
|
||||
|
||||
hpa := &autoscalingv1.HorizontalPodAutoscaler{
|
||||
hpa := &autoscaling.HorizontalPodAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "hpa1",
|
||||
Namespace: "default",
|
||||
@ -43,20 +42,25 @@ func TestUpdateHPAs(t *testing.T) {
|
||||
"metric-config.pods.requests-per-second.json-path/port": "9090",
|
||||
},
|
||||
},
|
||||
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
|
||||
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||
Kind: "Deployment",
|
||||
Name: "app",
|
||||
APIVersion: "apps/v1",
|
||||
},
|
||||
MinReplicas: &[]int32{1}[0],
|
||||
MaxReplicas: 10,
|
||||
Metrics: []autoscalingv1.MetricSpec{
|
||||
Metrics: []autoscaling.MetricSpec{
|
||||
{
|
||||
Type: autoscalingv1.PodsMetricSourceType,
|
||||
Pods: &autoscalingv1.PodsMetricSource{
|
||||
MetricName: "requests-per-second",
|
||||
TargetAverageValue: value,
|
||||
Type: autoscaling.PodsMetricSourceType,
|
||||
Pods: &autoscaling.PodsMetricSource{
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "requests-per-second",
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: &value,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -66,7 +70,7 @@ func TestUpdateHPAs(t *testing.T) {
|
||||
fakeClient := fake.NewSimpleClientset()
|
||||
|
||||
var err error
|
||||
hpa, err = fakeClient.AutoscalingV2beta1().HorizontalPodAutoscalers("default").Create(hpa)
|
||||
hpa, err = fakeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Create(hpa)
|
||||
require.NoError(t, err)
|
||||
|
||||
collectorFactory := collector.NewCollectorFactory()
|
||||
@ -82,7 +86,7 @@ func TestUpdateHPAs(t *testing.T) {
|
||||
|
||||
// update HPA
|
||||
hpa.Annotations["metric-config.pods.requests-per-second.json-path/port"] = "8080"
|
||||
_, err = fakeClient.AutoscalingV2beta1().HorizontalPodAutoscalers("default").Update(hpa)
|
||||
_, err = fakeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Update(hpa)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = provider.updateHPAs()
|
||||
|
Loading…
x
Reference in New Issue
Block a user