mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #90691 from arjunrn/container-resource-hpa
Add container based scaling to HPA
This commit is contained in:
commit
ec453ffb1a
125
api/openapi-spec/swagger.json
generated
125
api/openapi-spec/swagger.json
generated
@ -3024,6 +3024,61 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource": {
|
||||||
|
"description": "ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.",
|
||||||
|
"properties": {
|
||||||
|
"container": {
|
||||||
|
"description": "container is the name of the container in the pods of the scaling target",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "name is the name of the resource in question.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"targetAverageUtilization": {
|
||||||
|
"description": "targetAverageUtilization is the target value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.",
|
||||||
|
"format": "int32",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"targetAverageValue": {
|
||||||
|
"$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity",
|
||||||
|
"description": "targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"container"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricStatus": {
|
||||||
|
"description": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
"properties": {
|
||||||
|
"container": {
|
||||||
|
"description": "container is the name of the container in the pods of the scaling target",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currentAverageUtilization": {
|
||||||
|
"description": "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods. It will only be present if `targetAverageValue` was set in the corresponding metric specification.",
|
||||||
|
"format": "int32",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"currentAverageValue": {
|
||||||
|
"$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity",
|
||||||
|
"description": "currentAverageValue is the current value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type. It will always be set, regardless of the corresponding metric specification."
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "name is the name of the resource in question.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"currentAverageValue",
|
||||||
|
"container"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference": {
|
"io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference": {
|
||||||
"description": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
"description": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -3273,6 +3328,10 @@
|
|||||||
"io.k8s.api.autoscaling.v2beta1.MetricSpec": {
|
"io.k8s.api.autoscaling.v2beta1.MetricSpec": {
|
||||||
"description": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
"description": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"containerResource": {
|
||||||
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource",
|
||||||
|
"description": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag."
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta1.ExternalMetricSource",
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta1.ExternalMetricSource",
|
||||||
"description": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster)."
|
"description": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster)."
|
||||||
@ -3290,7 +3349,7 @@
|
|||||||
"description": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
"description": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"description": "type is the type of metric source. It should be one of \"Object\", \"Pods\", \"Resource\" or \"External\", each mapping to a matching field in the object.",
|
"description": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3302,6 +3361,10 @@
|
|||||||
"io.k8s.api.autoscaling.v2beta1.MetricStatus": {
|
"io.k8s.api.autoscaling.v2beta1.MetricStatus": {
|
||||||
"description": "MetricStatus describes the last-read state of a single metric.",
|
"description": "MetricStatus describes the last-read state of a single metric.",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"containerResource": {
|
||||||
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricStatus",
|
||||||
|
"description": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta1.ExternalMetricStatus",
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta1.ExternalMetricStatus",
|
||||||
"description": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster)."
|
"description": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster)."
|
||||||
@ -3319,7 +3382,7 @@
|
|||||||
"description": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
"description": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"description": "type is the type of metric source. It will be one of \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.",
|
"description": "type is the type of metric source. It will be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3479,6 +3542,52 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource": {
|
||||||
|
"description": "ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.",
|
||||||
|
"properties": {
|
||||||
|
"container": {
|
||||||
|
"description": "container is the name of the container in the pods of the scaling target",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "name is the name of the resource in question.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.MetricTarget",
|
||||||
|
"description": "target specifies the target value for the given metric"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"target",
|
||||||
|
"container"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricStatus": {
|
||||||
|
"description": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
"properties": {
|
||||||
|
"container": {
|
||||||
|
"description": "Container is the name of the container in the pods of the scaling target",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"current": {
|
||||||
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.MetricValueStatus",
|
||||||
|
"description": "current contains the current value for the given metric"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "Name is the name of the resource in question.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"current",
|
||||||
|
"container"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference": {
|
"io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference": {
|
||||||
"description": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
"description": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -3795,6 +3904,10 @@
|
|||||||
"io.k8s.api.autoscaling.v2beta2.MetricSpec": {
|
"io.k8s.api.autoscaling.v2beta2.MetricSpec": {
|
||||||
"description": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
"description": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"containerResource": {
|
||||||
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource",
|
||||||
|
"description": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag."
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.ExternalMetricSource",
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.ExternalMetricSource",
|
||||||
"description": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster)."
|
"description": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster)."
|
||||||
@ -3812,7 +3925,7 @@
|
|||||||
"description": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
"description": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"description": "type is the type of metric source. It should be one of \"Object\", \"Pods\", \"Resource\" or \"External\", each mapping to a matching field in the object.",
|
"description": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3824,6 +3937,10 @@
|
|||||||
"io.k8s.api.autoscaling.v2beta2.MetricStatus": {
|
"io.k8s.api.autoscaling.v2beta2.MetricStatus": {
|
||||||
"description": "MetricStatus describes the last-read state of a single metric.",
|
"description": "MetricStatus describes the last-read state of a single metric.",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"containerResource": {
|
||||||
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricStatus",
|
||||||
|
"description": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.ExternalMetricStatus",
|
"$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.ExternalMetricStatus",
|
||||||
"description": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster)."
|
"description": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster)."
|
||||||
@ -3841,7 +3958,7 @@
|
|||||||
"description": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
"description": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source."
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"description": "type is the type of metric source. It will be one of \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.",
|
"description": "type is the type of metric source. It will be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -204,6 +204,12 @@ const (
|
|||||||
// (for example length of queue in cloud messaging service, or
|
// (for example length of queue in cloud messaging service, or
|
||||||
// QPS from loadbalancer running outside of cluster).
|
// QPS from loadbalancer running outside of cluster).
|
||||||
ExternalMetricSourceType MetricSourceType = "External"
|
ExternalMetricSourceType MetricSourceType = "External"
|
||||||
|
// ContainerResourceMetricSourceType is a resource metric known to Kubernetes, as
|
||||||
|
// specified in requests and limits, describing a single container in each pod in the current
|
||||||
|
// scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics (the "pods" source).
|
||||||
|
ContainerResourceMetricSourceType MetricSourceType = "ContainerResource"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MetricSpec specifies how to scale based on a single metric
|
// MetricSpec specifies how to scale based on a single metric
|
||||||
@ -229,6 +235,13 @@ type MetricSpec struct {
|
|||||||
// to normal per-pod metrics using the "pods" source.
|
// to normal per-pod metrics using the "pods" source.
|
||||||
// +optional
|
// +optional
|
||||||
Resource *ResourceMetricSource
|
Resource *ResourceMetricSource
|
||||||
|
// ContainerResource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod of the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// +optional
|
||||||
|
ContainerResource *ContainerResourceMetricSource
|
||||||
// External refers to a global metric that is not associated
|
// External refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -271,6 +284,22 @@ type ResourceMetricSource struct {
|
|||||||
Target MetricTarget
|
Target MetricTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricSource indicates how to scale on a resource metric known to
|
||||||
|
// Kubernetes, as specified in the requests and limits, describing a single container in
|
||||||
|
// each of the pods of the current scale target(e.g. CPU or memory). The values will be
|
||||||
|
// averaged together before being compared to the target. Such metrics are built into
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source. Only one "target" type
|
||||||
|
// should be set.
|
||||||
|
type ContainerResourceMetricSource struct {
|
||||||
|
// name is the name of the of the resource
|
||||||
|
Name api.ResourceName
|
||||||
|
// container is the name of the container in the pods of the scaling target.
|
||||||
|
Container string
|
||||||
|
// target specifies the target value for the given metric
|
||||||
|
Target MetricTarget
|
||||||
|
}
|
||||||
|
|
||||||
// ExternalMetricSource indicates how to scale on a metric not associated with
|
// ExternalMetricSource indicates how to scale on a metric not associated with
|
||||||
// any Kubernetes object (for example length of queue in cloud
|
// any Kubernetes object (for example length of queue in cloud
|
||||||
// messaging service, or QPS from loadbalancer running outside of cluster).
|
// messaging service, or QPS from loadbalancer running outside of cluster).
|
||||||
@ -420,6 +449,13 @@ type MetricStatus struct {
|
|||||||
// to normal per-pod metrics using the "pods" source.
|
// to normal per-pod metrics using the "pods" source.
|
||||||
// +optional
|
// +optional
|
||||||
Resource *ResourceMetricStatus
|
Resource *ResourceMetricStatus
|
||||||
|
// ContainerResource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// +optional
|
||||||
|
ContainerResource *ContainerResourceMetricStatus
|
||||||
// External refers to a global metric that is not associated
|
// External refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -456,6 +492,18 @@ type ResourceMetricStatus struct {
|
|||||||
Current MetricValueStatus
|
Current MetricValueStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricStatus indicates the current value of a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source.
|
||||||
|
type ContainerResourceMetricStatus struct {
|
||||||
|
// Name is the name of the resource in question.
|
||||||
|
Name api.ResourceName
|
||||||
|
Container string
|
||||||
|
Current MetricValueStatus
|
||||||
|
}
|
||||||
|
|
||||||
// ExternalMetricStatus indicates the current value of a global metric
|
// ExternalMetricStatus indicates the current value of a global metric
|
||||||
// not associated with any Kubernetes object.
|
// not associated with any Kubernetes object.
|
||||||
type ExternalMetricStatus struct {
|
type ExternalMetricStatus struct {
|
||||||
|
@ -235,6 +235,28 @@ func Convert_autoscaling_ResourceMetricSource_To_v1_ResourceMetricSource(in *aut
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Convert_v1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(in *autoscalingv1.ContainerResourceMetricStatus, out *autoscaling.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
utilization := in.CurrentAverageUtilization
|
||||||
|
averageValue := &in.CurrentAverageValue
|
||||||
|
out.Current = autoscaling.MetricValueStatus{
|
||||||
|
AverageValue: averageValue,
|
||||||
|
AverageUtilization: utilization,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Convert_autoscaling_ContainerResourceMetricStatus_To_v1_ContainerResourceMetricStatus(in *autoscaling.ContainerResourceMetricStatus, out *autoscalingv1.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = v1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
out.CurrentAverageUtilization = in.Current.AverageUtilization
|
||||||
|
if in.Current.AverageValue != nil {
|
||||||
|
out.CurrentAverageValue = *in.Current.AverageValue
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func Convert_v1_ResourceMetricStatus_To_autoscaling_ResourceMetricStatus(in *autoscalingv1.ResourceMetricStatus, out *autoscaling.ResourceMetricStatus, s conversion.Scope) error {
|
func Convert_v1_ResourceMetricStatus_To_autoscaling_ResourceMetricStatus(in *autoscalingv1.ResourceMetricStatus, out *autoscaling.ResourceMetricStatus, s conversion.Scope) error {
|
||||||
out.Name = core.ResourceName(in.Name)
|
out.Name = core.ResourceName(in.Name)
|
||||||
utilization := in.CurrentAverageUtilization
|
utilization := in.CurrentAverageUtilization
|
||||||
@ -517,3 +539,30 @@ func Convert_v1_HorizontalPodAutoscalerStatus_To_autoscaling_HorizontalPodAutosc
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Convert_v1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(in *autoscalingv1.ContainerResourceMetricSource, out *autoscaling.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
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_ContainerResourceMetricSource_To_v1_ContainerResourceMetricSource(in *autoscaling.ContainerResourceMetricSource, out *autoscalingv1.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = v1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
out.TargetAverageUtilization = in.Target.AverageUtilization
|
||||||
|
out.TargetAverageValue = in.Target.AverageValue
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
86
pkg/apis/autoscaling/v1/zz_generated.conversion.go
generated
86
pkg/apis/autoscaling/v1/zz_generated.conversion.go
generated
@ -119,6 +119,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.AddConversionFunc((*autoscaling.ContainerResourceMetricSource)(nil), (*v1.ContainerResourceMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_autoscaling_ContainerResourceMetricSource_To_v1_ContainerResourceMetricSource(a.(*autoscaling.ContainerResourceMetricSource), b.(*v1.ContainerResourceMetricSource), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddConversionFunc((*autoscaling.ContainerResourceMetricStatus)(nil), (*v1.ContainerResourceMetricStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_autoscaling_ContainerResourceMetricStatus_To_v1_ContainerResourceMetricStatus(a.(*autoscaling.ContainerResourceMetricStatus), b.(*v1.ContainerResourceMetricStatus), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := s.AddConversionFunc((*autoscaling.ExternalMetricSource)(nil), (*v1.ExternalMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
if err := s.AddConversionFunc((*autoscaling.ExternalMetricSource)(nil), (*v1.ExternalMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
return Convert_autoscaling_ExternalMetricSource_To_v1_ExternalMetricSource(a.(*autoscaling.ExternalMetricSource), b.(*v1.ExternalMetricSource), scope)
|
return Convert_autoscaling_ExternalMetricSource_To_v1_ExternalMetricSource(a.(*autoscaling.ExternalMetricSource), b.(*v1.ExternalMetricSource), scope)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -179,6 +189,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.AddConversionFunc((*v1.ContainerResourceMetricSource)(nil), (*autoscaling.ContainerResourceMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_v1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(a.(*v1.ContainerResourceMetricSource), b.(*autoscaling.ContainerResourceMetricSource), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddConversionFunc((*v1.ContainerResourceMetricStatus)(nil), (*autoscaling.ContainerResourceMetricStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_v1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(a.(*v1.ContainerResourceMetricStatus), b.(*autoscaling.ContainerResourceMetricStatus), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := s.AddConversionFunc((*v1.CrossVersionObjectReference)(nil), (*autoscaling.MetricTarget)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
if err := s.AddConversionFunc((*v1.CrossVersionObjectReference)(nil), (*autoscaling.MetricTarget)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
return Convert_v1_CrossVersionObjectReference_To_autoscaling_MetricTarget(a.(*v1.CrossVersionObjectReference), b.(*autoscaling.MetricTarget), scope)
|
return Convert_v1_CrossVersionObjectReference_To_autoscaling_MetricTarget(a.(*v1.CrossVersionObjectReference), b.(*autoscaling.MetricTarget), scope)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -242,6 +262,36 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func autoConvert_v1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(in *v1.ContainerResourceMetricSource, out *autoscaling.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
// WARNING: in.TargetAverageUtilization requires manual conversion: does not exist in peer-type
|
||||||
|
// WARNING: in.TargetAverageValue requires manual conversion: does not exist in peer-type
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_autoscaling_ContainerResourceMetricSource_To_v1_ContainerResourceMetricSource(in *autoscaling.ContainerResourceMetricSource, out *v1.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = corev1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
// WARNING: in.Target requires manual conversion: does not exist in peer-type
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_v1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(in *v1.ContainerResourceMetricStatus, out *autoscaling.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
// WARNING: in.CurrentAverageUtilization requires manual conversion: does not exist in peer-type
|
||||||
|
// WARNING: in.CurrentAverageValue requires manual conversion: does not exist in peer-type
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_autoscaling_ContainerResourceMetricStatus_To_v1_ContainerResourceMetricStatus(in *autoscaling.ContainerResourceMetricStatus, out *v1.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = corev1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
// WARNING: in.Current requires manual conversion: does not exist in peer-type
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func autoConvert_v1_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(in *v1.CrossVersionObjectReference, out *autoscaling.CrossVersionObjectReference, s conversion.Scope) error {
|
func autoConvert_v1_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(in *v1.CrossVersionObjectReference, out *autoscaling.CrossVersionObjectReference, s conversion.Scope) error {
|
||||||
out.Kind = in.Kind
|
out.Kind = in.Kind
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
@ -455,6 +505,15 @@ func autoConvert_v1_MetricSpec_To_autoscaling_MetricSpec(in *v1.MetricSpec, out
|
|||||||
} else {
|
} else {
|
||||||
out.Resource = nil
|
out.Resource = nil
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(autoscaling.ContainerResourceMetricSource)
|
||||||
|
if err := Convert_v1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(autoscaling.ExternalMetricSource)
|
*out = new(autoscaling.ExternalMetricSource)
|
||||||
@ -501,6 +560,15 @@ func autoConvert_autoscaling_MetricSpec_To_v1_MetricSpec(in *autoscaling.MetricS
|
|||||||
} else {
|
} else {
|
||||||
out.Resource = nil
|
out.Resource = nil
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(v1.ContainerResourceMetricSource)
|
||||||
|
if err := Convert_autoscaling_ContainerResourceMetricSource_To_v1_ContainerResourceMetricSource(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(v1.ExternalMetricSource)
|
*out = new(v1.ExternalMetricSource)
|
||||||
@ -547,6 +615,15 @@ func autoConvert_v1_MetricStatus_To_autoscaling_MetricStatus(in *v1.MetricStatus
|
|||||||
} else {
|
} else {
|
||||||
out.Resource = nil
|
out.Resource = nil
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(autoscaling.ContainerResourceMetricStatus)
|
||||||
|
if err := Convert_v1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(autoscaling.ExternalMetricStatus)
|
*out = new(autoscaling.ExternalMetricStatus)
|
||||||
@ -593,6 +670,15 @@ func autoConvert_autoscaling_MetricStatus_To_v1_MetricStatus(in *autoscaling.Met
|
|||||||
} else {
|
} else {
|
||||||
out.Resource = nil
|
out.Resource = nil
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(v1.ContainerResourceMetricStatus)
|
||||||
|
if err := Convert_autoscaling_ContainerResourceMetricStatus_To_v1_ContainerResourceMetricStatus(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(v1.ExternalMetricStatus)
|
*out = new(v1.ExternalMetricStatus)
|
||||||
|
@ -35,6 +35,28 @@ func Convert_v2beta1_CrossVersionObjectReference_To_autoscaling_MetricTarget(in
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Convert_v2beta1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(in *autoscalingv2beta1.ContainerResourceMetricStatus, out *autoscaling.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
utilization := in.CurrentAverageUtilization
|
||||||
|
averageValue := in.CurrentAverageValue
|
||||||
|
out.Current = autoscaling.MetricValueStatus{
|
||||||
|
AverageValue: &averageValue,
|
||||||
|
AverageUtilization: utilization,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Convert_autoscaling_ContainerResourceMetricStatus_To_v2beta1_ContainerResourceMetricStatus(in *autoscaling.ContainerResourceMetricStatus, out *autoscalingv2beta1.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = v1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
out.CurrentAverageUtilization = in.Current.AverageUtilization
|
||||||
|
if in.Current.AverageValue != nil {
|
||||||
|
out.CurrentAverageValue = *in.Current.AverageValue
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func Convert_v2beta1_ResourceMetricStatus_To_autoscaling_ResourceMetricStatus(in *autoscalingv2beta1.ResourceMetricStatus, out *autoscaling.ResourceMetricStatus, s conversion.Scope) error {
|
func Convert_v2beta1_ResourceMetricStatus_To_autoscaling_ResourceMetricStatus(in *autoscalingv2beta1.ResourceMetricStatus, out *autoscaling.ResourceMetricStatus, s conversion.Scope) error {
|
||||||
out.Name = core.ResourceName(in.Name)
|
out.Name = core.ResourceName(in.Name)
|
||||||
utilization := in.CurrentAverageUtilization
|
utilization := in.CurrentAverageUtilization
|
||||||
@ -309,3 +331,29 @@ func Convert_v2beta1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutosca
|
|||||||
func Convert_autoscaling_HorizontalPodAutoscalerSpec_To_v2beta1_HorizontalPodAutoscalerSpec(in *autoscaling.HorizontalPodAutoscalerSpec, out *autoscalingv2beta1.HorizontalPodAutoscalerSpec, s conversion.Scope) error {
|
func Convert_autoscaling_HorizontalPodAutoscalerSpec_To_v2beta1_HorizontalPodAutoscalerSpec(in *autoscaling.HorizontalPodAutoscalerSpec, out *autoscalingv2beta1.HorizontalPodAutoscalerSpec, s conversion.Scope) error {
|
||||||
return autoConvert_autoscaling_HorizontalPodAutoscalerSpec_To_v2beta1_HorizontalPodAutoscalerSpec(in, out, s)
|
return autoConvert_autoscaling_HorizontalPodAutoscalerSpec_To_v2beta1_HorizontalPodAutoscalerSpec(in, out, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Convert_v2beta1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(in *autoscalingv2beta1.ContainerResourceMetricSource, out *autoscaling.ContainerResourceMetricSource, 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_ContainerResourceMetricSource_To_v2beta1_ContainerResourceMetricSource(in *autoscaling.ContainerResourceMetricSource, out *autoscalingv2beta1.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = v1.ResourceName(in.Name)
|
||||||
|
out.TargetAverageUtilization = in.Target.AverageUtilization
|
||||||
|
out.TargetAverageValue = in.Target.AverageValue
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -104,6 +104,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.AddConversionFunc((*autoscaling.ContainerResourceMetricSource)(nil), (*v2beta1.ContainerResourceMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_autoscaling_ContainerResourceMetricSource_To_v2beta1_ContainerResourceMetricSource(a.(*autoscaling.ContainerResourceMetricSource), b.(*v2beta1.ContainerResourceMetricSource), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddConversionFunc((*autoscaling.ContainerResourceMetricStatus)(nil), (*v2beta1.ContainerResourceMetricStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_autoscaling_ContainerResourceMetricStatus_To_v2beta1_ContainerResourceMetricStatus(a.(*autoscaling.ContainerResourceMetricStatus), b.(*v2beta1.ContainerResourceMetricStatus), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := s.AddConversionFunc((*autoscaling.ExternalMetricSource)(nil), (*v2beta1.ExternalMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
if err := s.AddConversionFunc((*autoscaling.ExternalMetricSource)(nil), (*v2beta1.ExternalMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
return Convert_autoscaling_ExternalMetricSource_To_v2beta1_ExternalMetricSource(a.(*autoscaling.ExternalMetricSource), b.(*v2beta1.ExternalMetricSource), scope)
|
return Convert_autoscaling_ExternalMetricSource_To_v2beta1_ExternalMetricSource(a.(*autoscaling.ExternalMetricSource), b.(*v2beta1.ExternalMetricSource), scope)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -159,6 +169,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.AddConversionFunc((*v2beta1.ContainerResourceMetricSource)(nil), (*autoscaling.ContainerResourceMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_v2beta1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(a.(*v2beta1.ContainerResourceMetricSource), b.(*autoscaling.ContainerResourceMetricSource), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddConversionFunc((*v2beta1.ContainerResourceMetricStatus)(nil), (*autoscaling.ContainerResourceMetricStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_v2beta1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(a.(*v2beta1.ContainerResourceMetricStatus), b.(*autoscaling.ContainerResourceMetricStatus), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := s.AddConversionFunc((*v2beta1.CrossVersionObjectReference)(nil), (*autoscaling.MetricTarget)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
if err := s.AddConversionFunc((*v2beta1.CrossVersionObjectReference)(nil), (*autoscaling.MetricTarget)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
return Convert_v2beta1_CrossVersionObjectReference_To_autoscaling_MetricTarget(a.(*v2beta1.CrossVersionObjectReference), b.(*autoscaling.MetricTarget), scope)
|
return Convert_v2beta1_CrossVersionObjectReference_To_autoscaling_MetricTarget(a.(*v2beta1.CrossVersionObjectReference), b.(*autoscaling.MetricTarget), scope)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -212,6 +232,36 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func autoConvert_v2beta1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(in *v2beta1.ContainerResourceMetricSource, out *autoscaling.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
// WARNING: in.TargetAverageUtilization requires manual conversion: does not exist in peer-type
|
||||||
|
// WARNING: in.TargetAverageValue requires manual conversion: does not exist in peer-type
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_autoscaling_ContainerResourceMetricSource_To_v2beta1_ContainerResourceMetricSource(in *autoscaling.ContainerResourceMetricSource, out *v2beta1.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = v1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
// WARNING: in.Target requires manual conversion: does not exist in peer-type
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_v2beta1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(in *v2beta1.ContainerResourceMetricStatus, out *autoscaling.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
// WARNING: in.CurrentAverageUtilization requires manual conversion: does not exist in peer-type
|
||||||
|
// WARNING: in.CurrentAverageValue requires manual conversion: does not exist in peer-type
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_autoscaling_ContainerResourceMetricStatus_To_v2beta1_ContainerResourceMetricStatus(in *autoscaling.ContainerResourceMetricStatus, out *v2beta1.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = v1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
// WARNING: in.Current requires manual conversion: does not exist in peer-type
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func autoConvert_v2beta1_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(in *v2beta1.CrossVersionObjectReference, out *autoscaling.CrossVersionObjectReference, s conversion.Scope) error {
|
func autoConvert_v2beta1_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(in *v2beta1.CrossVersionObjectReference, out *autoscaling.CrossVersionObjectReference, s conversion.Scope) error {
|
||||||
out.Kind = in.Kind
|
out.Kind = in.Kind
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
@ -481,6 +531,15 @@ func autoConvert_v2beta1_MetricSpec_To_autoscaling_MetricSpec(in *v2beta1.Metric
|
|||||||
} else {
|
} else {
|
||||||
out.Resource = nil
|
out.Resource = nil
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(autoscaling.ContainerResourceMetricSource)
|
||||||
|
if err := Convert_v2beta1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(autoscaling.ExternalMetricSource)
|
*out = new(autoscaling.ExternalMetricSource)
|
||||||
@ -527,6 +586,15 @@ func autoConvert_autoscaling_MetricSpec_To_v2beta1_MetricSpec(in *autoscaling.Me
|
|||||||
} else {
|
} else {
|
||||||
out.Resource = nil
|
out.Resource = nil
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(v2beta1.ContainerResourceMetricSource)
|
||||||
|
if err := Convert_autoscaling_ContainerResourceMetricSource_To_v2beta1_ContainerResourceMetricSource(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(v2beta1.ExternalMetricSource)
|
*out = new(v2beta1.ExternalMetricSource)
|
||||||
@ -573,6 +641,15 @@ func autoConvert_v2beta1_MetricStatus_To_autoscaling_MetricStatus(in *v2beta1.Me
|
|||||||
} else {
|
} else {
|
||||||
out.Resource = nil
|
out.Resource = nil
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(autoscaling.ContainerResourceMetricStatus)
|
||||||
|
if err := Convert_v2beta1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(autoscaling.ExternalMetricStatus)
|
*out = new(autoscaling.ExternalMetricStatus)
|
||||||
@ -619,6 +696,15 @@ func autoConvert_autoscaling_MetricStatus_To_v2beta1_MetricStatus(in *autoscalin
|
|||||||
} else {
|
} else {
|
||||||
out.Resource = nil
|
out.Resource = nil
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(v2beta1.ContainerResourceMetricStatus)
|
||||||
|
if err := Convert_autoscaling_ContainerResourceMetricStatus_To_v2beta1_ContainerResourceMetricStatus(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(v2beta1.ExternalMetricStatus)
|
*out = new(v2beta1.ExternalMetricStatus)
|
||||||
|
160
pkg/apis/autoscaling/v2beta2/zz_generated.conversion.go
generated
160
pkg/apis/autoscaling/v2beta2/zz_generated.conversion.go
generated
@ -40,6 +40,26 @@ func init() {
|
|||||||
// RegisterConversions adds conversion functions to the given scheme.
|
// RegisterConversions adds conversion functions to the given scheme.
|
||||||
// Public to allow building arbitrary schemes.
|
// Public to allow building arbitrary schemes.
|
||||||
func RegisterConversions(s *runtime.Scheme) error {
|
func RegisterConversions(s *runtime.Scheme) error {
|
||||||
|
if err := s.AddGeneratedConversionFunc((*v2beta2.ContainerResourceMetricSource)(nil), (*autoscaling.ContainerResourceMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_v2beta2_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(a.(*v2beta2.ContainerResourceMetricSource), b.(*autoscaling.ContainerResourceMetricSource), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddGeneratedConversionFunc((*autoscaling.ContainerResourceMetricSource)(nil), (*v2beta2.ContainerResourceMetricSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_autoscaling_ContainerResourceMetricSource_To_v2beta2_ContainerResourceMetricSource(a.(*autoscaling.ContainerResourceMetricSource), b.(*v2beta2.ContainerResourceMetricSource), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddGeneratedConversionFunc((*v2beta2.ContainerResourceMetricStatus)(nil), (*autoscaling.ContainerResourceMetricStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_v2beta2_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(a.(*v2beta2.ContainerResourceMetricStatus), b.(*autoscaling.ContainerResourceMetricStatus), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddGeneratedConversionFunc((*autoscaling.ContainerResourceMetricStatus)(nil), (*v2beta2.ContainerResourceMetricStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_autoscaling_ContainerResourceMetricStatus_To_v2beta2_ContainerResourceMetricStatus(a.(*autoscaling.ContainerResourceMetricStatus), b.(*v2beta2.ContainerResourceMetricStatus), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := s.AddGeneratedConversionFunc((*v2beta2.CrossVersionObjectReference)(nil), (*autoscaling.CrossVersionObjectReference)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
if err := s.AddGeneratedConversionFunc((*v2beta2.CrossVersionObjectReference)(nil), (*autoscaling.CrossVersionObjectReference)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
return Convert_v2beta2_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(a.(*v2beta2.CrossVersionObjectReference), b.(*autoscaling.CrossVersionObjectReference), scope)
|
return Convert_v2beta2_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(a.(*v2beta2.CrossVersionObjectReference), b.(*autoscaling.CrossVersionObjectReference), scope)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -263,6 +283,62 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func autoConvert_v2beta2_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(in *v2beta2.ContainerResourceMetricSource, out *autoscaling.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
if err := Convert_v2beta2_MetricTarget_To_autoscaling_MetricTarget(&in.Target, &out.Target, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert_v2beta2_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource is an autogenerated conversion function.
|
||||||
|
func Convert_v2beta2_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(in *v2beta2.ContainerResourceMetricSource, out *autoscaling.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
return autoConvert_v2beta2_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_autoscaling_ContainerResourceMetricSource_To_v2beta2_ContainerResourceMetricSource(in *autoscaling.ContainerResourceMetricSource, out *v2beta2.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
out.Name = v1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
if err := Convert_autoscaling_MetricTarget_To_v2beta2_MetricTarget(&in.Target, &out.Target, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert_autoscaling_ContainerResourceMetricSource_To_v2beta2_ContainerResourceMetricSource is an autogenerated conversion function.
|
||||||
|
func Convert_autoscaling_ContainerResourceMetricSource_To_v2beta2_ContainerResourceMetricSource(in *autoscaling.ContainerResourceMetricSource, out *v2beta2.ContainerResourceMetricSource, s conversion.Scope) error {
|
||||||
|
return autoConvert_autoscaling_ContainerResourceMetricSource_To_v2beta2_ContainerResourceMetricSource(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_v2beta2_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(in *v2beta2.ContainerResourceMetricStatus, out *autoscaling.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = core.ResourceName(in.Name)
|
||||||
|
if err := Convert_v2beta2_MetricValueStatus_To_autoscaling_MetricValueStatus(&in.Current, &out.Current, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert_v2beta2_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus is an autogenerated conversion function.
|
||||||
|
func Convert_v2beta2_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(in *v2beta2.ContainerResourceMetricStatus, out *autoscaling.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
return autoConvert_v2beta2_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_autoscaling_ContainerResourceMetricStatus_To_v2beta2_ContainerResourceMetricStatus(in *autoscaling.ContainerResourceMetricStatus, out *v2beta2.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
out.Name = v1.ResourceName(in.Name)
|
||||||
|
out.Container = in.Container
|
||||||
|
if err := Convert_autoscaling_MetricValueStatus_To_v2beta2_MetricValueStatus(&in.Current, &out.Current, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert_autoscaling_ContainerResourceMetricStatus_To_v2beta2_ContainerResourceMetricStatus is an autogenerated conversion function.
|
||||||
|
func Convert_autoscaling_ContainerResourceMetricStatus_To_v2beta2_ContainerResourceMetricStatus(in *autoscaling.ContainerResourceMetricStatus, out *v2beta2.ContainerResourceMetricStatus, s conversion.Scope) error {
|
||||||
|
return autoConvert_autoscaling_ContainerResourceMetricStatus_To_v2beta2_ContainerResourceMetricStatus(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
func autoConvert_v2beta2_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(in *v2beta2.CrossVersionObjectReference, out *autoscaling.CrossVersionObjectReference, s conversion.Scope) error {
|
func autoConvert_v2beta2_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(in *v2beta2.CrossVersionObjectReference, out *autoscaling.CrossVersionObjectReference, s conversion.Scope) error {
|
||||||
out.Kind = in.Kind
|
out.Kind = in.Kind
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
@ -515,7 +591,17 @@ func autoConvert_v2beta2_HorizontalPodAutoscalerSpec_To_autoscaling_HorizontalPo
|
|||||||
}
|
}
|
||||||
out.MinReplicas = (*int32)(unsafe.Pointer(in.MinReplicas))
|
out.MinReplicas = (*int32)(unsafe.Pointer(in.MinReplicas))
|
||||||
out.MaxReplicas = in.MaxReplicas
|
out.MaxReplicas = in.MaxReplicas
|
||||||
out.Metrics = *(*[]autoscaling.MetricSpec)(unsafe.Pointer(&in.Metrics))
|
if in.Metrics != nil {
|
||||||
|
in, out := &in.Metrics, &out.Metrics
|
||||||
|
*out = make([]autoscaling.MetricSpec, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
if err := Convert_v2beta2_MetricSpec_To_autoscaling_MetricSpec(&(*in)[i], &(*out)[i], s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.Metrics = nil
|
||||||
|
}
|
||||||
out.Behavior = (*autoscaling.HorizontalPodAutoscalerBehavior)(unsafe.Pointer(in.Behavior))
|
out.Behavior = (*autoscaling.HorizontalPodAutoscalerBehavior)(unsafe.Pointer(in.Behavior))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -531,7 +617,17 @@ func autoConvert_autoscaling_HorizontalPodAutoscalerSpec_To_v2beta2_HorizontalPo
|
|||||||
}
|
}
|
||||||
out.MinReplicas = (*int32)(unsafe.Pointer(in.MinReplicas))
|
out.MinReplicas = (*int32)(unsafe.Pointer(in.MinReplicas))
|
||||||
out.MaxReplicas = in.MaxReplicas
|
out.MaxReplicas = in.MaxReplicas
|
||||||
out.Metrics = *(*[]v2beta2.MetricSpec)(unsafe.Pointer(&in.Metrics))
|
if in.Metrics != nil {
|
||||||
|
in, out := &in.Metrics, &out.Metrics
|
||||||
|
*out = make([]v2beta2.MetricSpec, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
if err := Convert_autoscaling_MetricSpec_To_v2beta2_MetricSpec(&(*in)[i], &(*out)[i], s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.Metrics = nil
|
||||||
|
}
|
||||||
out.Behavior = (*v2beta2.HorizontalPodAutoscalerBehavior)(unsafe.Pointer(in.Behavior))
|
out.Behavior = (*v2beta2.HorizontalPodAutoscalerBehavior)(unsafe.Pointer(in.Behavior))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -546,7 +642,17 @@ func autoConvert_v2beta2_HorizontalPodAutoscalerStatus_To_autoscaling_Horizontal
|
|||||||
out.LastScaleTime = (*metav1.Time)(unsafe.Pointer(in.LastScaleTime))
|
out.LastScaleTime = (*metav1.Time)(unsafe.Pointer(in.LastScaleTime))
|
||||||
out.CurrentReplicas = in.CurrentReplicas
|
out.CurrentReplicas = in.CurrentReplicas
|
||||||
out.DesiredReplicas = in.DesiredReplicas
|
out.DesiredReplicas = in.DesiredReplicas
|
||||||
out.CurrentMetrics = *(*[]autoscaling.MetricStatus)(unsafe.Pointer(&in.CurrentMetrics))
|
if in.CurrentMetrics != nil {
|
||||||
|
in, out := &in.CurrentMetrics, &out.CurrentMetrics
|
||||||
|
*out = make([]autoscaling.MetricStatus, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
if err := Convert_v2beta2_MetricStatus_To_autoscaling_MetricStatus(&(*in)[i], &(*out)[i], s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.CurrentMetrics = nil
|
||||||
|
}
|
||||||
out.Conditions = *(*[]autoscaling.HorizontalPodAutoscalerCondition)(unsafe.Pointer(&in.Conditions))
|
out.Conditions = *(*[]autoscaling.HorizontalPodAutoscalerCondition)(unsafe.Pointer(&in.Conditions))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -561,7 +667,17 @@ func autoConvert_autoscaling_HorizontalPodAutoscalerStatus_To_v2beta2_Horizontal
|
|||||||
out.LastScaleTime = (*metav1.Time)(unsafe.Pointer(in.LastScaleTime))
|
out.LastScaleTime = (*metav1.Time)(unsafe.Pointer(in.LastScaleTime))
|
||||||
out.CurrentReplicas = in.CurrentReplicas
|
out.CurrentReplicas = in.CurrentReplicas
|
||||||
out.DesiredReplicas = in.DesiredReplicas
|
out.DesiredReplicas = in.DesiredReplicas
|
||||||
out.CurrentMetrics = *(*[]v2beta2.MetricStatus)(unsafe.Pointer(&in.CurrentMetrics))
|
if in.CurrentMetrics != nil {
|
||||||
|
in, out := &in.CurrentMetrics, &out.CurrentMetrics
|
||||||
|
*out = make([]v2beta2.MetricStatus, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
if err := Convert_autoscaling_MetricStatus_To_v2beta2_MetricStatus(&(*in)[i], &(*out)[i], s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.CurrentMetrics = nil
|
||||||
|
}
|
||||||
out.Conditions = *(*[]v2beta2.HorizontalPodAutoscalerCondition)(unsafe.Pointer(&in.Conditions))
|
out.Conditions = *(*[]v2beta2.HorizontalPodAutoscalerCondition)(unsafe.Pointer(&in.Conditions))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -598,6 +714,15 @@ func autoConvert_v2beta2_MetricSpec_To_autoscaling_MetricSpec(in *v2beta2.Metric
|
|||||||
out.Object = (*autoscaling.ObjectMetricSource)(unsafe.Pointer(in.Object))
|
out.Object = (*autoscaling.ObjectMetricSource)(unsafe.Pointer(in.Object))
|
||||||
out.Pods = (*autoscaling.PodsMetricSource)(unsafe.Pointer(in.Pods))
|
out.Pods = (*autoscaling.PodsMetricSource)(unsafe.Pointer(in.Pods))
|
||||||
out.Resource = (*autoscaling.ResourceMetricSource)(unsafe.Pointer(in.Resource))
|
out.Resource = (*autoscaling.ResourceMetricSource)(unsafe.Pointer(in.Resource))
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(autoscaling.ContainerResourceMetricSource)
|
||||||
|
if err := Convert_v2beta2_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
out.External = (*autoscaling.ExternalMetricSource)(unsafe.Pointer(in.External))
|
out.External = (*autoscaling.ExternalMetricSource)(unsafe.Pointer(in.External))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -612,6 +737,15 @@ func autoConvert_autoscaling_MetricSpec_To_v2beta2_MetricSpec(in *autoscaling.Me
|
|||||||
out.Object = (*v2beta2.ObjectMetricSource)(unsafe.Pointer(in.Object))
|
out.Object = (*v2beta2.ObjectMetricSource)(unsafe.Pointer(in.Object))
|
||||||
out.Pods = (*v2beta2.PodsMetricSource)(unsafe.Pointer(in.Pods))
|
out.Pods = (*v2beta2.PodsMetricSource)(unsafe.Pointer(in.Pods))
|
||||||
out.Resource = (*v2beta2.ResourceMetricSource)(unsafe.Pointer(in.Resource))
|
out.Resource = (*v2beta2.ResourceMetricSource)(unsafe.Pointer(in.Resource))
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(v2beta2.ContainerResourceMetricSource)
|
||||||
|
if err := Convert_autoscaling_ContainerResourceMetricSource_To_v2beta2_ContainerResourceMetricSource(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
out.External = (*v2beta2.ExternalMetricSource)(unsafe.Pointer(in.External))
|
out.External = (*v2beta2.ExternalMetricSource)(unsafe.Pointer(in.External))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -626,6 +760,15 @@ func autoConvert_v2beta2_MetricStatus_To_autoscaling_MetricStatus(in *v2beta2.Me
|
|||||||
out.Object = (*autoscaling.ObjectMetricStatus)(unsafe.Pointer(in.Object))
|
out.Object = (*autoscaling.ObjectMetricStatus)(unsafe.Pointer(in.Object))
|
||||||
out.Pods = (*autoscaling.PodsMetricStatus)(unsafe.Pointer(in.Pods))
|
out.Pods = (*autoscaling.PodsMetricStatus)(unsafe.Pointer(in.Pods))
|
||||||
out.Resource = (*autoscaling.ResourceMetricStatus)(unsafe.Pointer(in.Resource))
|
out.Resource = (*autoscaling.ResourceMetricStatus)(unsafe.Pointer(in.Resource))
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(autoscaling.ContainerResourceMetricStatus)
|
||||||
|
if err := Convert_v2beta2_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
out.External = (*autoscaling.ExternalMetricStatus)(unsafe.Pointer(in.External))
|
out.External = (*autoscaling.ExternalMetricStatus)(unsafe.Pointer(in.External))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -640,6 +783,15 @@ func autoConvert_autoscaling_MetricStatus_To_v2beta2_MetricStatus(in *autoscalin
|
|||||||
out.Object = (*v2beta2.ObjectMetricStatus)(unsafe.Pointer(in.Object))
|
out.Object = (*v2beta2.ObjectMetricStatus)(unsafe.Pointer(in.Object))
|
||||||
out.Pods = (*v2beta2.PodsMetricStatus)(unsafe.Pointer(in.Pods))
|
out.Pods = (*v2beta2.PodsMetricStatus)(unsafe.Pointer(in.Pods))
|
||||||
out.Resource = (*v2beta2.ResourceMetricStatus)(unsafe.Pointer(in.Resource))
|
out.Resource = (*v2beta2.ResourceMetricStatus)(unsafe.Pointer(in.Resource))
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(v2beta2.ContainerResourceMetricStatus)
|
||||||
|
if err := Convert_autoscaling_ContainerResourceMetricStatus_To_v2beta2_ContainerResourceMetricStatus(*in, *out, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.ContainerResource = nil
|
||||||
|
}
|
||||||
out.External = (*v2beta2.ExternalMetricStatus)(unsafe.Pointer(in.External))
|
out.External = (*v2beta2.ExternalMetricStatus)(unsafe.Pointer(in.External))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ go_library(
|
|||||||
importpath = "k8s.io/kubernetes/pkg/apis/autoscaling/validation",
|
importpath = "k8s.io/kubernetes/pkg/apis/autoscaling/validation",
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/apis/autoscaling:go_default_library",
|
"//pkg/apis/autoscaling:go_default_library",
|
||||||
|
"//pkg/apis/core/v1/validation:go_default_library",
|
||||||
"//pkg/apis/core/validation:go_default_library",
|
"//pkg/apis/core/validation:go_default_library",
|
||||||
"//pkg/features:go_default_library",
|
"//pkg/features:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library",
|
||||||
|
@ -18,14 +18,13 @@ package validation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
|
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||||
pathvalidation "k8s.io/apimachinery/pkg/api/validation/path"
|
pathvalidation "k8s.io/apimachinery/pkg/api/validation/path"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||||
|
corevalidation "k8s.io/kubernetes/pkg/apis/core/v1/validation"
|
||||||
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
|
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
)
|
)
|
||||||
@ -239,7 +238,10 @@ func validateScalingPolicy(policy autoscaling.HPAScalingPolicy, fldPath *field.P
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
var validMetricSourceTypes = sets.NewString(string(autoscaling.ObjectMetricSourceType), string(autoscaling.PodsMetricSourceType), string(autoscaling.ResourceMetricSourceType), string(autoscaling.ExternalMetricSourceType))
|
var validMetricSourceTypes = sets.NewString(
|
||||||
|
string(autoscaling.ObjectMetricSourceType), string(autoscaling.PodsMetricSourceType),
|
||||||
|
string(autoscaling.ResourceMetricSourceType), string(autoscaling.ExternalMetricSourceType),
|
||||||
|
string(autoscaling.ContainerResourceMetricSourceType))
|
||||||
var validMetricSourceTypesList = validMetricSourceTypes.List()
|
var validMetricSourceTypesList = validMetricSourceTypes.List()
|
||||||
|
|
||||||
func validateMetricSpec(spec autoscaling.MetricSpec, fldPath *field.Path) field.ErrorList {
|
func validateMetricSpec(spec autoscaling.MetricSpec, fldPath *field.Path) field.ErrorList {
|
||||||
@ -282,10 +284,47 @@ func validateMetricSpec(spec autoscaling.MetricSpec, fldPath *field.Path) field.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedField := strings.ToLower(string(spec.Type))
|
if spec.ContainerResource != nil {
|
||||||
|
typesPresent.Insert("containerResource")
|
||||||
|
if typesPresent.Len() == 1 {
|
||||||
|
allErrs = append(allErrs, validateContainerResourceSource(spec.ContainerResource, fldPath.Child("containerResource"))...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !typesPresent.Has(expectedField) {
|
var expectedField string
|
||||||
allErrs = append(allErrs, field.Required(fldPath.Child(expectedField), "must populate information for the given metric source"))
|
switch spec.Type {
|
||||||
|
|
||||||
|
case autoscaling.ObjectMetricSourceType:
|
||||||
|
if spec.Object == nil {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("object"), "must populate information for the given metric source"))
|
||||||
|
}
|
||||||
|
expectedField = "object"
|
||||||
|
case autoscaling.PodsMetricSourceType:
|
||||||
|
if spec.Pods == nil {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("pods"), "must populate information for the given metric source"))
|
||||||
|
}
|
||||||
|
expectedField = "pods"
|
||||||
|
case autoscaling.ResourceMetricSourceType:
|
||||||
|
if spec.Resource == nil {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("resource"), "must populate information for the given metric source"))
|
||||||
|
}
|
||||||
|
expectedField = "resource"
|
||||||
|
case autoscaling.ExternalMetricSourceType:
|
||||||
|
if spec.External == nil {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("external"), "must populate information for the given metric source"))
|
||||||
|
}
|
||||||
|
expectedField = "external"
|
||||||
|
case autoscaling.ContainerResourceMetricSourceType:
|
||||||
|
if spec.ContainerResource == nil {
|
||||||
|
if utilfeature.DefaultFeatureGate.Enabled(features.HPAContainerMetrics) {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("containerResource"), "must populate information for the given metric source"))
|
||||||
|
} else {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("containerResource"), "must populate information for the given metric source (only allowed when HPAContainerMetrics feature is enabled)"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectedField = "containerResource"
|
||||||
|
default:
|
||||||
|
allErrs = append(allErrs, field.NotSupported(fldPath.Child("type"), spec.Type, validMetricSourceTypesList))
|
||||||
}
|
}
|
||||||
|
|
||||||
if typesPresent.Len() != 1 {
|
if typesPresent.Len() != 1 {
|
||||||
@ -342,6 +381,34 @@ func validatePodsSource(src *autoscaling.PodsMetricSource, fldPath *field.Path)
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateContainerResourceSource(src *autoscaling.ContainerResourceMetricSource, fldPath *field.Path) field.ErrorList {
|
||||||
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
|
if len(src.Name) == 0 {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("name"), "must specify a resource name"))
|
||||||
|
} else {
|
||||||
|
allErrs = append(allErrs, corevalidation.ValidateContainerResourceName(string(src.Name), fldPath.Child("name"))...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src.Container) == 0 {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("container"), "must specify a container"))
|
||||||
|
} else {
|
||||||
|
allErrs = append(allErrs, apivalidation.ValidateDNS1123Label(src.Container, fldPath.Child("container"))...)
|
||||||
|
}
|
||||||
|
|
||||||
|
allErrs = append(allErrs, validateMetricTarget(src.Target, fldPath.Child("target"))...)
|
||||||
|
|
||||||
|
if src.Target.AverageUtilization == nil && src.Target.AverageValue == nil {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("target").Child("averageUtilization"), "must set either a target raw value or a target utilization"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if src.Target.AverageUtilization != nil && src.Target.AverageValue != nil {
|
||||||
|
allErrs = append(allErrs, field.Forbidden(fldPath.Child("target").Child("averageValue"), "may not set both a target raw value and a target utilization"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
|
||||||
func validateResourceSource(src *autoscaling.ResourceMetricSource, fldPath *field.Path) field.ErrorList {
|
func validateResourceSource(src *autoscaling.ResourceMetricSource, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
|
@ -565,6 +565,60 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "myautoscaler",
|
||||||
|
Namespace: metav1.NamespaceDefault,
|
||||||
|
},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
Name: "myrc",
|
||||||
|
},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-container",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(70),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "myautoscaler",
|
||||||
|
Namespace: metav1.NamespaceDefault,
|
||||||
|
},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
Name: "myrc",
|
||||||
|
},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-container",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.AverageValueMetricType,
|
||||||
|
AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "myautoscaler",
|
Name: "myautoscaler",
|
||||||
@ -689,6 +743,30 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
msg: "scaleTargetRef.kind: Required",
|
msg: "scaleTargetRef.kind: Required",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(70),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "scaleTargetRef.kind: Required",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
@ -712,6 +790,30 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
msg: "scaleTargetRef.kind: Invalid",
|
msg: "scaleTargetRef.kind: Invalid",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "..", Name: "myrc"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(70),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "scaleTargetRef.kind: Invalid",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
@ -735,6 +837,30 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
msg: "scaleTargetRef.name: Required",
|
msg: "scaleTargetRef.name: Required",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(70),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "scaleTargetRef.name: Required",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
@ -758,6 +884,30 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
msg: "scaleTargetRef.name: Invalid",
|
msg: "scaleTargetRef.name: Invalid",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController", Name: ".."},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(70),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "scaleTargetRef.name: Invalid",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@ -813,6 +963,34 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
msg: "may not set both a target raw value and a target utilization",
|
msg: "may not set both a target raw value and a target utilization",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "myautoscaler",
|
||||||
|
Namespace: metav1.NamespaceDefault,
|
||||||
|
},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(70),
|
||||||
|
AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "may not set both a target raw value and a target utilization",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
@ -835,6 +1013,53 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
msg: "must specify a resource name",
|
msg: "must specify a resource name",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(70),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "must specify a resource name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: "InvalidResource",
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(70),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "Invalid value: \"InvalidResource\": must be a standard resource type or fully qualified",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
@ -858,6 +1083,77 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
msg: "must be greater than 0",
|
msg: "must be greater than 0",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(-10),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "must be greater than 0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(-10),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "must specify a container",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "---***",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(-10),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "Invalid value: \"---***\"",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
@ -880,6 +1176,29 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
msg: "must set either a target raw value or a target utilization",
|
msg: "must set either a target raw value or a target utilization",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
|
||||||
|
MinReplicas: utilpointer.Int32Ptr(1),
|
||||||
|
MaxReplicas: 5,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.ValueMetricType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
msg: "must set either a target raw value or a target utilization",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
|
||||||
@ -1321,6 +1640,16 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
autoscaling.ContainerResourceMetricSourceType: {
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "test-application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.AverageValueMetricType,
|
||||||
|
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
autoscaling.PodsMetricSourceType: {
|
autoscaling.PodsMetricSourceType: {
|
||||||
Pods: &autoscaling.PodsMetricSource{
|
Pods: &autoscaling.PodsMetricSource{
|
||||||
Metric: autoscaling.MetricIdentifier{
|
Metric: autoscaling.MetricIdentifier{
|
||||||
|
44
pkg/apis/autoscaling/zz_generated.deepcopy.go
generated
44
pkg/apis/autoscaling/zz_generated.deepcopy.go
generated
@ -25,6 +25,40 @@ import (
|
|||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ContainerResourceMetricSource) DeepCopyInto(out *ContainerResourceMetricSource) {
|
||||||
|
*out = *in
|
||||||
|
in.Target.DeepCopyInto(&out.Target)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricSource.
|
||||||
|
func (in *ContainerResourceMetricSource) DeepCopy() *ContainerResourceMetricSource {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ContainerResourceMetricSource)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ContainerResourceMetricStatus) DeepCopyInto(out *ContainerResourceMetricStatus) {
|
||||||
|
*out = *in
|
||||||
|
in.Current.DeepCopyInto(&out.Current)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricStatus.
|
||||||
|
func (in *ContainerResourceMetricStatus) DeepCopy() *ContainerResourceMetricStatus {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ContainerResourceMetricStatus)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@ -340,6 +374,11 @@ func (in *MetricSpec) DeepCopyInto(out *MetricSpec) {
|
|||||||
*out = new(ResourceMetricSource)
|
*out = new(ResourceMetricSource)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(ContainerResourceMetricSource)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(ExternalMetricSource)
|
*out = new(ExternalMetricSource)
|
||||||
@ -376,6 +415,11 @@ func (in *MetricStatus) DeepCopyInto(out *MetricStatus) {
|
|||||||
*out = new(ResourceMetricStatus)
|
*out = new(ResourceMetricStatus)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(ContainerResourceMetricStatus)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(ExternalMetricStatus)
|
*out = new(ExternalMetricStatus)
|
||||||
|
@ -42,7 +42,7 @@ func ValidateResourceRequirements(requirements *v1.ResourceRequirements, fldPath
|
|||||||
for resourceName, quantity := range requirements.Limits {
|
for resourceName, quantity := range requirements.Limits {
|
||||||
fldPath := limPath.Key(string(resourceName))
|
fldPath := limPath.Key(string(resourceName))
|
||||||
// Validate resource name.
|
// Validate resource name.
|
||||||
allErrs = append(allErrs, validateContainerResourceName(string(resourceName), fldPath)...)
|
allErrs = append(allErrs, ValidateContainerResourceName(string(resourceName), fldPath)...)
|
||||||
|
|
||||||
// Validate resource quantity.
|
// Validate resource quantity.
|
||||||
allErrs = append(allErrs, ValidateResourceQuantityValue(string(resourceName), quantity, fldPath)...)
|
allErrs = append(allErrs, ValidateResourceQuantityValue(string(resourceName), quantity, fldPath)...)
|
||||||
@ -51,7 +51,7 @@ func ValidateResourceRequirements(requirements *v1.ResourceRequirements, fldPath
|
|||||||
for resourceName, quantity := range requirements.Requests {
|
for resourceName, quantity := range requirements.Requests {
|
||||||
fldPath := reqPath.Key(string(resourceName))
|
fldPath := reqPath.Key(string(resourceName))
|
||||||
// Validate resource name.
|
// Validate resource name.
|
||||||
allErrs = append(allErrs, validateContainerResourceName(string(resourceName), fldPath)...)
|
allErrs = append(allErrs, ValidateContainerResourceName(string(resourceName), fldPath)...)
|
||||||
// Validate resource quantity.
|
// Validate resource quantity.
|
||||||
allErrs = append(allErrs, ValidateResourceQuantityValue(string(resourceName), quantity, fldPath)...)
|
allErrs = append(allErrs, ValidateResourceQuantityValue(string(resourceName), quantity, fldPath)...)
|
||||||
|
|
||||||
@ -70,7 +70,8 @@ func ValidateResourceRequirements(requirements *v1.ResourceRequirements, fldPath
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateContainerResourceName(value string, fldPath *field.Path) field.ErrorList {
|
// ValidateContainerResourceName checks the name of resource specified for a container
|
||||||
|
func ValidateContainerResourceName(value string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := validateResourceName(value, fldPath)
|
allErrs := validateResourceName(value, fldPath)
|
||||||
if len(strings.Split(value, "/")) == 1 {
|
if len(strings.Split(value, "/")) == 1 {
|
||||||
if !helper.IsStandardContainerResourceName(value) {
|
if !helper.IsStandardContainerResourceName(value) {
|
||||||
|
@ -129,6 +129,62 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateContainerResourceName(t *testing.T) {
|
||||||
|
successCase := []struct {
|
||||||
|
Name string
|
||||||
|
ResourceName string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "CPU resource",
|
||||||
|
ResourceName: "cpu",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Memory resource",
|
||||||
|
ResourceName: "memory",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Hugepages resource",
|
||||||
|
ResourceName: "hugepages-2Mi",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Namespaced resource",
|
||||||
|
ResourceName: "kubernetes.io/resource-foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Extended Resource",
|
||||||
|
ResourceName: "my.org/resource-bar",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range successCase {
|
||||||
|
if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) != 0 {
|
||||||
|
t.Errorf("%q unexpected error: %v", tc.Name, errs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errorCase := []struct {
|
||||||
|
Name string
|
||||||
|
ResourceName string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "Invalid standard resource",
|
||||||
|
ResourceName: "cpu-core",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Invalid namespaced resource",
|
||||||
|
ResourceName: "kubernetes.io/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Invalid extended resource",
|
||||||
|
ResourceName: "my.org-foo-resource",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range errorCase {
|
||||||
|
if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) == 0 {
|
||||||
|
t.Errorf("%q expected error", tc.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidatePodLogOptions(t *testing.T) {
|
func TestValidatePodLogOptions(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -329,6 +329,11 @@ func (a *HorizontalController) computeReplicasForMetric(hpa *autoscalingv2.Horiz
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, "", time.Time{}, condition, err
|
return 0, "", time.Time{}, condition, err
|
||||||
}
|
}
|
||||||
|
case autoscalingv2.ContainerResourceMetricSourceType:
|
||||||
|
replicaCountProposal, timestampProposal, metricNameProposal, condition, err = a.computeStatusForContainerResourceMetric(specReplicas, spec, hpa, selector, status)
|
||||||
|
if err != nil {
|
||||||
|
return 0, "", time.Time{}, condition, err
|
||||||
|
}
|
||||||
case autoscalingv2.ExternalMetricSourceType:
|
case autoscalingv2.ExternalMetricSourceType:
|
||||||
replicaCountProposal, timestampProposal, metricNameProposal, condition, err = a.computeStatusForExternalMetric(specReplicas, statusReplicas, spec, hpa, selector, status)
|
replicaCountProposal, timestampProposal, metricNameProposal, condition, err = a.computeStatusForExternalMetric(specReplicas, statusReplicas, spec, hpa, selector, status)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -435,51 +440,80 @@ func (a *HorizontalController) computeStatusForPodsMetric(currentReplicas int32,
|
|||||||
return replicaCountProposal, timestampProposal, fmt.Sprintf("pods metric %s", metricSpec.Pods.Metric.Name), autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
return replicaCountProposal, timestampProposal, fmt.Sprintf("pods metric %s", metricSpec.Pods.Metric.Name), autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// computeStatusForResourceMetric computes the desired number of replicas for the specified metric of type ResourceMetricSourceType.
|
func (a *HorizontalController) computeStatusForResourceMetricGeneric(currentReplicas int32, target autoscalingv2.MetricTarget,
|
||||||
func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (replicaCountProposal int32, timestampProposal time.Time, metricNameProposal string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
resourceName v1.ResourceName, namespace string, container string, selector labels.Selector) (replicaCountProposal int32,
|
||||||
if metricSpec.Resource.Target.AverageValue != nil {
|
metricStatus *autoscalingv2.MetricValueStatus, timestampProposal time.Time, metricNameProposal string,
|
||||||
|
condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
||||||
|
if target.AverageValue != nil {
|
||||||
var rawProposal int64
|
var rawProposal int64
|
||||||
replicaCountProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetRawResourceReplicas(currentReplicas, metricSpec.Resource.Target.AverageValue.MilliValue(), metricSpec.Resource.Name, hpa.Namespace, selector)
|
replicaCountProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetRawResourceReplicas(currentReplicas, target.AverageValue.MilliValue(), resourceName, namespace, selector, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetResourceMetric", err)
|
return 0, nil, time.Time{}, "", condition, fmt.Errorf("failed to get %s utilization: %v", resourceName, err)
|
||||||
return 0, time.Time{}, "", condition, fmt.Errorf("failed to get %s utilization: %v", metricSpec.Resource.Name, err)
|
|
||||||
}
|
}
|
||||||
metricNameProposal = fmt.Sprintf("%s resource", metricSpec.Resource.Name)
|
metricNameProposal = fmt.Sprintf("%s resource", resourceName.String())
|
||||||
*status = autoscalingv2.MetricStatus{
|
status := autoscalingv2.MetricValueStatus{
|
||||||
Type: autoscalingv2.ResourceMetricSourceType,
|
AverageValue: resource.NewMilliQuantity(rawProposal, resource.DecimalSI),
|
||||||
Resource: &autoscalingv2.ResourceMetricStatus{
|
|
||||||
Name: metricSpec.Resource.Name,
|
|
||||||
Current: autoscalingv2.MetricValueStatus{
|
|
||||||
AverageValue: resource.NewMilliQuantity(rawProposal, resource.DecimalSI),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return replicaCountProposal, timestampProposal, metricNameProposal, autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
return replicaCountProposal, &status, timestampProposal, metricNameProposal, autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
||||||
}
|
}
|
||||||
if metricSpec.Resource.Target.AverageUtilization == nil {
|
|
||||||
|
if target.AverageUtilization == nil {
|
||||||
errMsg := "invalid resource metric source: neither a utilization target nor a value target was set"
|
errMsg := "invalid resource metric source: neither a utilization target nor a value target was set"
|
||||||
err = fmt.Errorf(errMsg)
|
err = fmt.Errorf(errMsg)
|
||||||
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetResourceMetric", err)
|
return 0, nil, time.Time{}, "", condition, fmt.Errorf(errMsg)
|
||||||
return 0, time.Time{}, "", condition, fmt.Errorf(errMsg)
|
|
||||||
}
|
}
|
||||||
targetUtilization := *metricSpec.Resource.Target.AverageUtilization
|
|
||||||
replicaCountProposal, percentageProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetResourceReplicas(currentReplicas, targetUtilization, metricSpec.Resource.Name, hpa.Namespace, selector)
|
targetUtilization := *target.AverageUtilization
|
||||||
|
replicaCountProposal, percentageProposal, rawProposal, timestampProposal, err := a.replicaCalc.GetResourceReplicas(currentReplicas, targetUtilization, resourceName, namespace, selector, container)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, time.Time{}, "", condition, fmt.Errorf("failed to get %s utilization: %v", resourceName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
metricNameProposal = fmt.Sprintf("%s resource utilization (percentage of request)", resourceName)
|
||||||
|
status := autoscalingv2.MetricValueStatus{
|
||||||
|
AverageUtilization: &percentageProposal,
|
||||||
|
AverageValue: resource.NewMilliQuantity(rawProposal, resource.DecimalSI),
|
||||||
|
}
|
||||||
|
return replicaCountProposal, &status, timestampProposal, metricNameProposal, autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeStatusForResourceMetric computes the desired number of replicas for the specified metric of type ResourceMetricSourceType.
|
||||||
|
func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler,
|
||||||
|
selector labels.Selector, status *autoscalingv2.MetricStatus) (replicaCountProposal int32, timestampProposal time.Time,
|
||||||
|
metricNameProposal string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
||||||
|
replicaCountProposal, metricValueStatus, timestampProposal, metricNameProposal, condition, err := a.computeStatusForResourceMetricGeneric(currentReplicas, metricSpec.Resource.Target, metricSpec.Resource.Name, hpa.Namespace, "", selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetResourceMetric", err)
|
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetResourceMetric", err)
|
||||||
return 0, time.Time{}, "", condition, fmt.Errorf("failed to get %s utilization: %v", metricSpec.Resource.Name, err)
|
return replicaCountProposal, timestampProposal, metricNameProposal, condition, err
|
||||||
}
|
}
|
||||||
metricNameProposal = fmt.Sprintf("%s resource utilization (percentage of request)", metricSpec.Resource.Name)
|
|
||||||
*status = autoscalingv2.MetricStatus{
|
*status = autoscalingv2.MetricStatus{
|
||||||
Type: autoscalingv2.ResourceMetricSourceType,
|
Type: autoscalingv2.ResourceMetricSourceType,
|
||||||
Resource: &autoscalingv2.ResourceMetricStatus{
|
Resource: &autoscalingv2.ResourceMetricStatus{
|
||||||
Name: metricSpec.Resource.Name,
|
Name: metricSpec.Resource.Name,
|
||||||
Current: autoscalingv2.MetricValueStatus{
|
Current: *metricValueStatus,
|
||||||
AverageUtilization: &percentageProposal,
|
|
||||||
AverageValue: resource.NewMilliQuantity(rawProposal, resource.DecimalSI),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return replicaCountProposal, timestampProposal, metricNameProposal, autoscalingv2.HorizontalPodAutoscalerCondition{}, nil
|
return replicaCountProposal, timestampProposal, metricNameProposal, condition, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeStatusForContainerResourceMetric computes the desired number of replicas for the specified metric of type ResourceMetricSourceType.
|
||||||
|
func (a *HorizontalController) computeStatusForContainerResourceMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler,
|
||||||
|
selector labels.Selector, status *autoscalingv2.MetricStatus) (replicaCountProposal int32, timestampProposal time.Time,
|
||||||
|
metricNameProposal string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) {
|
||||||
|
replicaCountProposal, metricValueStatus, timestampProposal, metricNameProposal, condition, err := a.computeStatusForResourceMetricGeneric(currentReplicas, metricSpec.ContainerResource.Target, metricSpec.ContainerResource.Name, hpa.Namespace, metricSpec.ContainerResource.Container, selector)
|
||||||
|
if err != nil {
|
||||||
|
condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetContainerResourceMetric", err)
|
||||||
|
return replicaCountProposal, timestampProposal, metricNameProposal, condition, err
|
||||||
|
}
|
||||||
|
*status = autoscalingv2.MetricStatus{
|
||||||
|
Type: autoscalingv2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2.ContainerResourceMetricStatus{
|
||||||
|
Name: metricSpec.ContainerResource.Name,
|
||||||
|
Container: metricSpec.ContainerResource.Container,
|
||||||
|
Current: *metricValueStatus,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return replicaCountProposal, timestampProposal, metricNameProposal, condition, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// computeStatusForExternalMetric computes the desired number of replicas for the specified metric of type ExternalMetricSourceType.
|
// computeStatusForExternalMetric computes the desired number of replicas for the specified metric of type ExternalMetricSourceType.
|
||||||
@ -783,7 +817,7 @@ func getReplicasChangePerPeriod(periodSeconds int32, scaleEvents []timestampedSc
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *HorizontalController) getUnableComputeReplicaCountCondition(hpa *autoscalingv2.HorizontalPodAutoscaler, reason string, err error) (condition autoscalingv2.HorizontalPodAutoscalerCondition) {
|
func (a *HorizontalController) getUnableComputeReplicaCountCondition(hpa runtime.Object, reason string, err error) (condition autoscalingv2.HorizontalPodAutoscalerCondition) {
|
||||||
a.eventRecorder.Event(hpa, v1.EventTypeWarning, reason, err.Error())
|
a.eventRecorder.Event(hpa, v1.EventTypeWarning, reason, err.Error())
|
||||||
return autoscalingv2.HorizontalPodAutoscalerCondition{
|
return autoscalingv2.HorizontalPodAutoscalerCondition{
|
||||||
Type: autoscalingv2.ScalingActive,
|
Type: autoscalingv2.ScalingActive,
|
||||||
|
@ -336,9 +336,18 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
|||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
Containers: []v1.Container{
|
Containers: []v1.Container{
|
||||||
{
|
{
|
||||||
|
Name: "container1",
|
||||||
Resources: v1.ResourceRequirements{
|
Resources: v1.ResourceRequirements{
|
||||||
Requests: v1.ResourceList{
|
Requests: v1.ResourceList{
|
||||||
v1.ResourceCPU: reportedCPURequest,
|
v1.ResourceCPU: *resource.NewMilliQuantity(reportedCPURequest.MilliValue()/2, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "container2",
|
||||||
|
Resources: v1.ResourceRequirements{
|
||||||
|
Requests: v1.ResourceList{
|
||||||
|
v1.ResourceCPU: *resource.NewMilliQuantity(reportedCPURequest.MilliValue()/2, resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -509,13 +518,24 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
|
|||||||
Window: metav1.Duration{Duration: time.Minute},
|
Window: metav1.Duration{Duration: time.Minute},
|
||||||
Containers: []metricsapi.ContainerMetrics{
|
Containers: []metricsapi.ContainerMetrics{
|
||||||
{
|
{
|
||||||
Name: "container",
|
Name: "container1",
|
||||||
Usage: v1.ResourceList{
|
Usage: v1.ResourceList{
|
||||||
v1.ResourceCPU: *resource.NewMilliQuantity(
|
v1.ResourceCPU: *resource.NewMilliQuantity(
|
||||||
int64(cpu),
|
int64(cpu/2),
|
||||||
resource.DecimalSI),
|
resource.DecimalSI),
|
||||||
v1.ResourceMemory: *resource.NewQuantity(
|
v1.ResourceMemory: *resource.NewQuantity(
|
||||||
int64(1024*1024),
|
int64(1024*1024/2),
|
||||||
|
resource.BinarySI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "container2",
|
||||||
|
Usage: v1.ResourceList{
|
||||||
|
v1.ResourceCPU: *resource.NewMilliQuantity(
|
||||||
|
int64(cpu/2),
|
||||||
|
resource.DecimalSI),
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(
|
||||||
|
int64(1024*1024/2),
|
||||||
resource.BinarySI),
|
resource.BinarySI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -773,6 +793,31 @@ func TestScaleUp(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestScaleUpContainer(t *testing.T) {
|
||||||
|
tc := testCase{
|
||||||
|
minReplicas: 2,
|
||||||
|
maxReplicas: 6,
|
||||||
|
specReplicas: 3,
|
||||||
|
statusReplicas: 3,
|
||||||
|
expectedDesiredReplicas: 5,
|
||||||
|
metricsTarget: []autoscalingv2.MetricSpec{{
|
||||||
|
Type: autoscalingv2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2.ContainerResourceMetricSource{
|
||||||
|
Name: v1.ResourceCPU,
|
||||||
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(30),
|
||||||
|
},
|
||||||
|
Container: "container1",
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
reportedLevels: []uint64{300, 500, 700},
|
||||||
|
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
useMetricsAPI: true,
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestScaleUpUnreadyLessScale(t *testing.T) {
|
func TestScaleUpUnreadyLessScale(t *testing.T) {
|
||||||
tc := testCase{
|
tc := testCase{
|
||||||
minReplicas: 2,
|
minReplicas: 2,
|
||||||
@ -1269,6 +1314,32 @@ func TestScaleDown(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestScaleDownContainerResource(t *testing.T) {
|
||||||
|
tc := testCase{
|
||||||
|
minReplicas: 2,
|
||||||
|
maxReplicas: 6,
|
||||||
|
specReplicas: 5,
|
||||||
|
statusReplicas: 5,
|
||||||
|
expectedDesiredReplicas: 3,
|
||||||
|
reportedLevels: []uint64{100, 300, 500, 250, 250},
|
||||||
|
reportedCPURequests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
metricsTarget: []autoscalingv2.MetricSpec{{
|
||||||
|
Type: autoscalingv2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2.ContainerResourceMetricSource{
|
||||||
|
Container: "container2",
|
||||||
|
Name: v1.ResourceCPU,
|
||||||
|
Target: autoscalingv2.MetricTarget{
|
||||||
|
Type: autoscalingv2.UtilizationMetricType,
|
||||||
|
AverageUtilization: utilpointer.Int32Ptr(50),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
useMetricsAPI: true,
|
||||||
|
recommendations: []timestampedRecommendation{},
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestScaleDownWithScalingRules(t *testing.T) {
|
func TestScaleDownWithScalingRules(t *testing.T) {
|
||||||
tc := testCase{
|
tc := testCase{
|
||||||
minReplicas: 2,
|
minReplicas: 2,
|
||||||
@ -2809,7 +2880,7 @@ func TestScaleDownRCImmediately(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAvoidUncessaryUpdates(t *testing.T) {
|
func TestAvoidUnnecessaryUpdates(t *testing.T) {
|
||||||
now := metav1.Time{Time: time.Now().Add(-time.Hour)}
|
now := metav1.Time{Time: time.Now().Add(-time.Hour)}
|
||||||
tc := testCase{
|
tc := testCase{
|
||||||
minReplicas: 2,
|
minReplicas: 2,
|
||||||
|
@ -126,14 +126,11 @@ func (tc *legacyReplicaCalcTestCase) prepareTestClient(t *testing.T) *fake.Clien
|
|||||||
Timestamp: metav1.Time{Time: tc.timestamp},
|
Timestamp: metav1.Time{Time: tc.timestamp},
|
||||||
Containers: make([]metricsapi.ContainerMetrics, numContainersPerPod),
|
Containers: make([]metricsapi.ContainerMetrics, numContainersPerPod),
|
||||||
}
|
}
|
||||||
|
for i, m := range resValue {
|
||||||
for i := 0; i < numContainersPerPod; i++ {
|
|
||||||
podMetric.Containers[i] = metricsapi.ContainerMetrics{
|
podMetric.Containers[i] = metricsapi.ContainerMetrics{
|
||||||
Name: fmt.Sprintf("container%v", i),
|
Name: fmt.Sprintf("container%v", i),
|
||||||
Usage: v1.ResourceList{
|
Usage: v1.ResourceList{
|
||||||
v1.ResourceName(tc.resource.name): *resource.NewMilliQuantity(
|
tc.resource.name: *resource.NewMilliQuantity(m, resource.DecimalSI),
|
||||||
int64(resValue),
|
|
||||||
resource.DecimalSI),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +206,7 @@ func (tc *legacyReplicaCalcTestCase) runTest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tc.resource != nil {
|
if tc.resource != nil {
|
||||||
outReplicas, outUtilization, outRawValue, outTimestamp, err := replicaCalc.GetResourceReplicas(tc.currentReplicas, tc.resource.targetUtilization, tc.resource.name, testNamespace, selector)
|
outReplicas, outUtilization, outRawValue, outTimestamp, err := replicaCalc.GetResourceReplicas(tc.currentReplicas, tc.resource.targetUtilization, tc.resource.name, testNamespace, selector, "")
|
||||||
|
|
||||||
if tc.expectedError != nil {
|
if tc.expectedError != nil {
|
||||||
require.Error(t, err, "there should be an error calculating the replica count")
|
require.Error(t, err, "there should be an error calculating the replica count")
|
||||||
@ -244,7 +241,7 @@ func TestLegacyReplicaCalcDisjointResourcesMetrics(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0")},
|
||||||
levels: []int64{100},
|
levels: makePodMetricLevels(100),
|
||||||
podNames: []string{"an-older-pod-name"},
|
podNames: []string{"an-older-pod-name"},
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
@ -260,7 +257,7 @@ func TestLegacyReplicaCalcScaleUp(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{300, 500, 700},
|
levels: makePodMetricLevels(300, 500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 50,
|
expectedUtilization: 50,
|
||||||
@ -278,7 +275,7 @@ func TestLegacyReplicaCalcScaleUpUnreadyLessScale(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{300, 500, 700},
|
levels: makePodMetricLevels(300, 500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 60,
|
expectedUtilization: 60,
|
||||||
@ -296,7 +293,7 @@ func TestLegacyReplicaCalcScaleUpUnreadyNoScale(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{400, 500, 700},
|
levels: makePodMetricLevels(400, 500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 40,
|
expectedUtilization: 40,
|
||||||
@ -357,7 +354,7 @@ func TestLegacyReplicaCalcScaleDown(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 300, 500, 250, 250},
|
levels: makePodMetricLevels(100, 300, 500, 250, 250),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 28,
|
expectedUtilization: 28,
|
||||||
@ -389,7 +386,7 @@ func TestLegacyReplicaCalcScaleDownIgnoresUnreadyPods(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 300, 500, 250, 250},
|
levels: makePodMetricLevels(100, 300, 500, 250, 250),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 30,
|
expectedUtilization: 30,
|
||||||
@ -406,7 +403,7 @@ func TestLegacyReplicaCalcTolerance(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")},
|
requests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")},
|
||||||
levels: []int64{1010, 1030, 1020},
|
levels: makePodMetricLevels(1010, 1030, 1020),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 102,
|
expectedUtilization: 102,
|
||||||
@ -437,7 +434,7 @@ func TestLegacyReplicaCalcSuperfluousMetrics(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{4000, 9500, 3000, 7000, 3200, 2000},
|
levels: makePodMetricLevels(4000, 9500, 3000, 7000, 3200, 2000),
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 587,
|
expectedUtilization: 587,
|
||||||
expectedValue: numContainersPerPod * 5875,
|
expectedValue: numContainersPerPod * 5875,
|
||||||
@ -453,7 +450,7 @@ func TestLegacyReplicaCalcMissingMetrics(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{400, 95},
|
levels: makePodMetricLevels(400, 95),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 24,
|
expectedUtilization: 24,
|
||||||
@ -470,7 +467,7 @@ func TestLegacyReplicaCalcEmptyMetrics(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{},
|
levels: makePodMetricLevels(),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
},
|
},
|
||||||
@ -485,7 +482,7 @@ func TestLegacyReplicaCalcEmptyCPURequest(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{},
|
requests: []resource.Quantity{},
|
||||||
levels: []int64{200},
|
levels: makePodMetricLevels(200),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
},
|
},
|
||||||
@ -500,7 +497,7 @@ func TestLegacyReplicaCalcMissingMetricsNoChangeEq(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{1000},
|
levels: makePodMetricLevels(1000),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 100,
|
expectedUtilization: 100,
|
||||||
@ -517,7 +514,7 @@ func TestLegacyReplicaCalcMissingMetricsNoChangeGt(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{1900},
|
levels: makePodMetricLevels(1900),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 190,
|
expectedUtilization: 190,
|
||||||
@ -534,7 +531,7 @@ func TestLegacyReplicaCalcMissingMetricsNoChangeLt(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{600},
|
levels: makePodMetricLevels(600),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 60,
|
expectedUtilization: 60,
|
||||||
@ -552,7 +549,7 @@ func TestLegacyReplicaCalcMissingMetricsUnreadyNoChange(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 450},
|
levels: makePodMetricLevels(100, 450),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 45,
|
expectedUtilization: 45,
|
||||||
@ -570,7 +567,7 @@ func TestLegacyReplicaCalcMissingMetricsUnreadyScaleUp(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 2000},
|
levels: makePodMetricLevels(100, 2000),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 200,
|
expectedUtilization: 200,
|
||||||
@ -588,7 +585,7 @@ func TestLegacyReplicaCalcMissingMetricsUnreadyScaleDown(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 100, 100},
|
levels: makePodMetricLevels(100, 100, 100),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 10,
|
expectedUtilization: 10,
|
||||||
@ -627,18 +624,18 @@ func TestLegacyReplicaCalcComputedToleranceAlgImplementation(t *testing.T) {
|
|||||||
expectedReplicas: finalPods,
|
expectedReplicas: finalPods,
|
||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
levels: []int64{
|
levels: makePodMetricLevels(
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
},
|
),
|
||||||
requests: []resource.Quantity{
|
requests: []resource.Quantity{
|
||||||
resource.MustParse(fmt.Sprint(perPodRequested+100) + "m"),
|
resource.MustParse(fmt.Sprint(perPodRequested+100) + "m"),
|
||||||
resource.MustParse(fmt.Sprint(perPodRequested-100) + "m"),
|
resource.MustParse(fmt.Sprint(perPodRequested-100) + "m"),
|
||||||
|
@ -20,6 +20,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta2:go_default_library",
|
"//staging/src/k8s.io/metrics/pkg/apis/custom_metrics/v1beta2:go_default_library",
|
||||||
"//staging/src/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
|
"//staging/src/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/metrics/pkg/apis/metrics/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1:go_default_library",
|
"//staging/src/k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/metrics/pkg/client/custom_metrics:go_default_library",
|
"//staging/src/k8s.io/metrics/pkg/client/custom_metrics:go_default_library",
|
||||||
"//staging/src/k8s.io/metrics/pkg/client/external_metrics:go_default_library",
|
"//staging/src/k8s.io/metrics/pkg/client/external_metrics:go_default_library",
|
||||||
|
@ -38,8 +38,9 @@ type PodMetricsInfo map[string]PodMetric
|
|||||||
// resource metrics as well as pod-level arbitrary metrics
|
// resource metrics as well as pod-level arbitrary metrics
|
||||||
type MetricsClient interface {
|
type MetricsClient interface {
|
||||||
// GetResourceMetric gets the given resource metric (and an associated oldest timestamp)
|
// GetResourceMetric gets the given resource metric (and an associated oldest timestamp)
|
||||||
// for all pods matching the specified selector in the given namespace
|
// for the specified named container in all pods matching the specified selector in the given namespace and when
|
||||||
GetResourceMetric(resource v1.ResourceName, namespace string, selector labels.Selector) (PodMetricsInfo, time.Time, error)
|
// the container is an empty string it returns the sum of all the container metrics.
|
||||||
|
GetResourceMetric(resource v1.ResourceName, namespace string, selector labels.Selector, container string) (PodMetricsInfo, time.Time, error)
|
||||||
|
|
||||||
// GetRawMetric gets the given metric (and an associated oldest timestamp)
|
// GetRawMetric gets the given metric (and an associated oldest timestamp)
|
||||||
// for all pods matching the specified selector in the given namespace
|
// for all pods matching the specified selector in the given namespace
|
||||||
|
@ -63,7 +63,7 @@ func NewHeapsterMetricsClient(client clientset.Interface, namespace, scheme, ser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HeapsterMetricsClient) GetResourceMetric(resource v1.ResourceName, namespace string, selector labels.Selector) (PodMetricsInfo, time.Time, error) {
|
func (h *HeapsterMetricsClient) GetResourceMetric(resource v1.ResourceName, namespace string, selector labels.Selector, container string) (PodMetricsInfo, time.Time, error) {
|
||||||
metricPath := fmt.Sprintf("/apis/metrics/v1alpha1/namespaces/%s/pods", namespace)
|
metricPath := fmt.Sprintf("/apis/metrics/v1alpha1/namespaces/%s/pods", namespace)
|
||||||
params := map[string]string{"labelSelector": selector.String()}
|
params := map[string]string{"labelSelector": selector.String()}
|
||||||
|
|
||||||
@ -92,13 +92,15 @@ func (h *HeapsterMetricsClient) GetResourceMetric(resource v1.ResourceName, name
|
|||||||
podSum := int64(0)
|
podSum := int64(0)
|
||||||
missing := len(m.Containers) == 0
|
missing := len(m.Containers) == 0
|
||||||
for _, c := range m.Containers {
|
for _, c := range m.Containers {
|
||||||
resValue, found := c.Usage[v1.ResourceName(resource)]
|
if container == "" || container == c.Name {
|
||||||
if !found {
|
resValue, found := c.Usage[v1.ResourceName(resource)]
|
||||||
missing = true
|
if !found {
|
||||||
klog.V(2).Infof("missing resource metric %v for container %s in pod %s/%s", resource, c.Name, namespace, m.Name)
|
missing = true
|
||||||
continue
|
klog.V(2).Infof("missing resource metric %v for container %s in pod %s/%s", resource, c.Name, namespace, m.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
podSum += resValue.MilliValue()
|
||||||
}
|
}
|
||||||
podSum += resValue.MilliValue()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !missing {
|
if !missing {
|
||||||
|
@ -222,7 +222,7 @@ func (tc *testCase) runTest(t *testing.T) {
|
|||||||
metricsClient := NewHeapsterMetricsClient(testClient, DefaultHeapsterNamespace, DefaultHeapsterScheme, DefaultHeapsterService, DefaultHeapsterPort)
|
metricsClient := NewHeapsterMetricsClient(testClient, DefaultHeapsterNamespace, DefaultHeapsterScheme, DefaultHeapsterService, DefaultHeapsterPort)
|
||||||
isResource := len(tc.resourceName) > 0
|
isResource := len(tc.resourceName) > 0
|
||||||
if isResource {
|
if isResource {
|
||||||
info, timestamp, err := metricsClient.GetResourceMetric(tc.resourceName, tc.namespace, tc.selector)
|
info, timestamp, err := metricsClient.GetResourceMetric(tc.resourceName, tc.namespace, tc.selector, "")
|
||||||
tc.verifyResults(t, info, timestamp, err)
|
tc.verifyResults(t, info, timestamp, err)
|
||||||
} else {
|
} else {
|
||||||
info, timestamp, err := metricsClient.GetRawMetric(tc.metricName, tc.namespace, tc.selector, tc.metricSelector)
|
info, timestamp, err := metricsClient.GetRawMetric(tc.metricName, tc.namespace, tc.selector, tc.metricSelector)
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
customapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
customapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
|
||||||
|
metricsapi "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||||
resourceclient "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1"
|
resourceclient "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1"
|
||||||
customclient "k8s.io/metrics/pkg/client/custom_metrics"
|
customclient "k8s.io/metrics/pkg/client/custom_metrics"
|
||||||
externalclient "k8s.io/metrics/pkg/client/external_metrics"
|
externalclient "k8s.io/metrics/pkg/client/external_metrics"
|
||||||
@ -63,7 +64,7 @@ type resourceMetricsClient struct {
|
|||||||
|
|
||||||
// GetResourceMetric gets the given resource metric (and an associated oldest timestamp)
|
// GetResourceMetric gets the given resource metric (and an associated oldest timestamp)
|
||||||
// for all pods matching the specified selector in the given namespace
|
// for all pods matching the specified selector in the given namespace
|
||||||
func (c *resourceMetricsClient) GetResourceMetric(resource v1.ResourceName, namespace string, selector labels.Selector) (PodMetricsInfo, time.Time, error) {
|
func (c *resourceMetricsClient) GetResourceMetric(resource v1.ResourceName, namespace string, selector labels.Selector, container string) (PodMetricsInfo, time.Time, error) {
|
||||||
metrics, err := c.client.PodMetricses(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: selector.String()})
|
metrics, err := c.client.PodMetricses(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: selector.String()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err)
|
return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err)
|
||||||
@ -72,34 +73,66 @@ func (c *resourceMetricsClient) GetResourceMetric(resource v1.ResourceName, name
|
|||||||
if len(metrics.Items) == 0 {
|
if len(metrics.Items) == 0 {
|
||||||
return nil, time.Time{}, fmt.Errorf("no metrics returned from resource metrics API")
|
return nil, time.Time{}, fmt.Errorf("no metrics returned from resource metrics API")
|
||||||
}
|
}
|
||||||
|
var res PodMetricsInfo
|
||||||
|
if container != "" {
|
||||||
|
res, err = getContainerMetrics(metrics.Items, resource, container)
|
||||||
|
if err != nil {
|
||||||
|
return nil, time.Time{}, fmt.Errorf("failed to get container metrics: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = getPodMetrics(metrics.Items, resource)
|
||||||
|
}
|
||||||
|
timestamp := metrics.Items[0].Timestamp.Time
|
||||||
|
return res, timestamp, nil
|
||||||
|
}
|
||||||
|
|
||||||
res := make(PodMetricsInfo, len(metrics.Items))
|
func getContainerMetrics(rawMetrics []metricsapi.PodMetrics, resource v1.ResourceName, container string) (PodMetricsInfo, error) {
|
||||||
|
res := make(PodMetricsInfo, len(rawMetrics))
|
||||||
|
for _, m := range rawMetrics {
|
||||||
|
containerFound := false
|
||||||
|
for _, c := range m.Containers {
|
||||||
|
if c.Name == container {
|
||||||
|
containerFound = true
|
||||||
|
if val, resFound := c.Usage[resource]; resFound {
|
||||||
|
res[m.Name] = PodMetric{
|
||||||
|
Timestamp: m.Timestamp.Time,
|
||||||
|
Window: m.Window.Duration,
|
||||||
|
Value: val.MilliValue(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !containerFound {
|
||||||
|
return nil, fmt.Errorf("container %s not present in metrics for pod %s/%s", container, m.Namespace, m.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
for _, m := range metrics.Items {
|
func getPodMetrics(rawMetrics []metricsapi.PodMetrics, resource v1.ResourceName) PodMetricsInfo {
|
||||||
|
res := make(PodMetricsInfo, len(rawMetrics))
|
||||||
|
for _, m := range rawMetrics {
|
||||||
podSum := int64(0)
|
podSum := int64(0)
|
||||||
missing := len(m.Containers) == 0
|
missing := len(m.Containers) == 0
|
||||||
for _, c := range m.Containers {
|
for _, c := range m.Containers {
|
||||||
resValue, found := c.Usage[v1.ResourceName(resource)]
|
resValue, found := c.Usage[resource]
|
||||||
if !found {
|
if !found {
|
||||||
missing = true
|
missing = true
|
||||||
klog.V(2).Infof("missing resource metric %v for container %s in pod %s/%s", resource, c.Name, namespace, m.Name)
|
klog.V(2).Infof("missing resource metric %v for %s/%s", resource, m.Namespace, m.Name)
|
||||||
break // containers loop
|
break
|
||||||
}
|
}
|
||||||
podSum += resValue.MilliValue()
|
podSum += resValue.MilliValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !missing {
|
if !missing {
|
||||||
res[m.Name] = PodMetric{
|
res[m.Name] = PodMetric{
|
||||||
Timestamp: m.Timestamp.Time,
|
Timestamp: m.Timestamp.Time,
|
||||||
Window: m.Window.Duration,
|
Window: m.Window.Duration,
|
||||||
Value: int64(podSum),
|
Value: podSum,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return res
|
||||||
timestamp := metrics.Items[0].Timestamp.Time
|
|
||||||
|
|
||||||
return res, timestamp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// customMetricsClient implements the custom-metrics-related parts of MetricsClient,
|
// customMetricsClient implements the custom-metrics-related parts of MetricsClient,
|
||||||
|
@ -50,12 +50,13 @@ type restClientTestCase struct {
|
|||||||
targetTimestamp int
|
targetTimestamp int
|
||||||
window time.Duration
|
window time.Duration
|
||||||
reportedMetricPoints []metricPoint
|
reportedMetricPoints []metricPoint
|
||||||
reportedPodMetrics [][]int64
|
reportedPodMetrics []map[string]int64
|
||||||
singleObject *autoscalingapi.CrossVersionObjectReference
|
singleObject *autoscalingapi.CrossVersionObjectReference
|
||||||
|
|
||||||
namespace string
|
namespace string
|
||||||
selector labels.Selector
|
selector labels.Selector
|
||||||
resourceName v1.ResourceName
|
resourceName v1.ResourceName
|
||||||
|
container string
|
||||||
metricName string
|
metricName string
|
||||||
metricSelector *metav1.LabelSelector
|
metricSelector *metav1.LabelSelector
|
||||||
metricLabelSelector labels.Selector
|
metricLabelSelector labels.Selector
|
||||||
@ -91,9 +92,9 @@ func (tc *restClientTestCase) prepareTestClient(t *testing.T) (*metricsfake.Clie
|
|||||||
Window: metav1.Duration{Duration: tc.window},
|
Window: metav1.Duration{Duration: tc.window},
|
||||||
Containers: []metricsapi.ContainerMetrics{},
|
Containers: []metricsapi.ContainerMetrics{},
|
||||||
}
|
}
|
||||||
for j, cpu := range containers {
|
for containerName, cpu := range containers {
|
||||||
cm := metricsapi.ContainerMetrics{
|
cm := metricsapi.ContainerMetrics{
|
||||||
Name: fmt.Sprintf("%s-%d-container-%d", podNamePrefix, i, j),
|
Name: containerName,
|
||||||
Usage: v1.ResourceList{
|
Usage: v1.ResourceList{
|
||||||
v1.ResourceCPU: *resource.NewMilliQuantity(
|
v1.ResourceCPU: *resource.NewMilliQuantity(
|
||||||
cpu,
|
cpu,
|
||||||
@ -230,7 +231,7 @@ func (tc *restClientTestCase) runTest(t *testing.T) {
|
|||||||
isResource := len(tc.resourceName) > 0
|
isResource := len(tc.resourceName) > 0
|
||||||
isExternal := tc.metricSelector != nil
|
isExternal := tc.metricSelector != nil
|
||||||
if isResource {
|
if isResource {
|
||||||
info, timestamp, err := metricsClient.GetResourceMetric(v1.ResourceName(tc.resourceName), tc.namespace, tc.selector)
|
info, timestamp, err := metricsClient.GetResourceMetric(v1.ResourceName(tc.resourceName), tc.namespace, tc.selector, tc.container)
|
||||||
tc.verifyResults(t, info, timestamp, err)
|
tc.verifyResults(t, info, timestamp, err)
|
||||||
} else if isExternal {
|
} else if isExternal {
|
||||||
tc.metricLabelSelector, err = metav1.LabelSelectorAsSelector(tc.metricSelector)
|
tc.metricLabelSelector, err = metav1.LabelSelectorAsSelector(tc.metricSelector)
|
||||||
@ -253,7 +254,7 @@ func (tc *restClientTestCase) runTest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRESTClientCPU(t *testing.T) {
|
func TestRESTClientPodCPU(t *testing.T) {
|
||||||
targetTimestamp := 1
|
targetTimestamp := 1
|
||||||
window := 30 * time.Second
|
window := 30 * time.Second
|
||||||
tc := restClientTestCase{
|
tc := restClientTestCase{
|
||||||
@ -265,7 +266,25 @@ func TestRESTClientCPU(t *testing.T) {
|
|||||||
resourceName: v1.ResourceCPU,
|
resourceName: v1.ResourceCPU,
|
||||||
targetTimestamp: targetTimestamp,
|
targetTimestamp: targetTimestamp,
|
||||||
window: window,
|
window: window,
|
||||||
reportedPodMetrics: [][]int64{{5000}, {5000}, {5000}},
|
reportedPodMetrics: []map[string]int64{{"test": 5000}, {"test": 5000}, {"test": 5000}},
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRESTClientContainerCPU(t *testing.T) {
|
||||||
|
targetTimestamp := 1
|
||||||
|
window := 30 * time.Second
|
||||||
|
tc := restClientTestCase{
|
||||||
|
desiredMetricValues: PodMetricsInfo{
|
||||||
|
"test-pod-0": {Value: 5000, Timestamp: offsetTimestampBy(targetTimestamp), Window: window},
|
||||||
|
"test-pod-1": {Value: 5000, Timestamp: offsetTimestampBy(targetTimestamp), Window: window},
|
||||||
|
"test-pod-2": {Value: 5000, Timestamp: offsetTimestampBy(targetTimestamp), Window: window},
|
||||||
|
},
|
||||||
|
container: "test-1",
|
||||||
|
resourceName: v1.ResourceCPU,
|
||||||
|
targetTimestamp: targetTimestamp,
|
||||||
|
window: window,
|
||||||
|
reportedPodMetrics: []map[string]int64{{"test-1": 5000, "test-2": 500}, {"test-1": 5000, "test-2": 500}, {"test-1": 5000, "test-2": 500}},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
@ -362,17 +381,17 @@ func TestRESTClientExternalEmptyMetrics(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRESTClientCPUEmptyMetrics(t *testing.T) {
|
func TestRESTClientPodCPUEmptyMetrics(t *testing.T) {
|
||||||
tc := restClientTestCase{
|
tc := restClientTestCase{
|
||||||
resourceName: v1.ResourceCPU,
|
resourceName: v1.ResourceCPU,
|
||||||
desiredError: fmt.Errorf("no metrics returned from resource metrics API"),
|
desiredError: fmt.Errorf("no metrics returned from resource metrics API"),
|
||||||
reportedMetricPoints: []metricPoint{},
|
reportedMetricPoints: []metricPoint{},
|
||||||
reportedPodMetrics: [][]int64{},
|
reportedPodMetrics: []map[string]int64{},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRESTClientCPUEmptyMetricsForOnePod(t *testing.T) {
|
func TestRESTClientPodCPUEmptyMetricsForOnePod(t *testing.T) {
|
||||||
targetTimestamp := 1
|
targetTimestamp := 1
|
||||||
window := 30 * time.Second
|
window := 30 * time.Second
|
||||||
tc := restClientTestCase{
|
tc := restClientTestCase{
|
||||||
@ -383,7 +402,25 @@ func TestRESTClientCPUEmptyMetricsForOnePod(t *testing.T) {
|
|||||||
},
|
},
|
||||||
targetTimestamp: targetTimestamp,
|
targetTimestamp: targetTimestamp,
|
||||||
window: window,
|
window: window,
|
||||||
reportedPodMetrics: [][]int64{{100}, {300, 400}, {}},
|
reportedPodMetrics: []map[string]int64{{"test-1": 100}, {"test-1": 300, "test-2": 400}, {}},
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRESTClientContainerCPUEmptyMetricsForOnePod(t *testing.T) {
|
||||||
|
targetTimestamp := 1
|
||||||
|
window := 30 * time.Second
|
||||||
|
tc := restClientTestCase{
|
||||||
|
resourceName: v1.ResourceCPU,
|
||||||
|
desiredMetricValues: PodMetricsInfo{
|
||||||
|
"test-pod-0": {Value: 100, Timestamp: offsetTimestampBy(targetTimestamp), Window: window},
|
||||||
|
"test-pod-1": {Value: 300, Timestamp: offsetTimestampBy(targetTimestamp), Window: window},
|
||||||
|
},
|
||||||
|
container: "test-1",
|
||||||
|
targetTimestamp: targetTimestamp,
|
||||||
|
window: window,
|
||||||
|
desiredError: fmt.Errorf("failed to get container metrics"),
|
||||||
|
reportedPodMetrics: []map[string]int64{{"test-1": 100}, {"test-1": 300, "test-2": 400}, {}},
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ func NewReplicaCalculator(metricsClient metricsclient.MetricsClient, podLister c
|
|||||||
|
|
||||||
// GetResourceReplicas calculates the desired replica count based on a target resource utilization percentage
|
// GetResourceReplicas calculates the desired replica count based on a target resource utilization percentage
|
||||||
// of the given resource for pods matching the given selector in the given namespace, and the current replica count
|
// of the given resource for pods matching the given selector in the given namespace, and the current replica count
|
||||||
func (c *ReplicaCalculator) GetResourceReplicas(currentReplicas int32, targetUtilization int32, resource v1.ResourceName, namespace string, selector labels.Selector) (replicaCount int32, utilization int32, rawUtilization int64, timestamp time.Time, err error) {
|
func (c *ReplicaCalculator) GetResourceReplicas(currentReplicas int32, targetUtilization int32, resource v1.ResourceName, namespace string, selector labels.Selector, container string) (replicaCount int32, utilization int32, rawUtilization int64, timestamp time.Time, err error) {
|
||||||
metrics, timestamp, err := c.metricsClient.GetResourceMetric(resource, namespace, selector)
|
metrics, timestamp, err := c.metricsClient.GetResourceMetric(resource, namespace, selector, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, 0, time.Time{}, fmt.Errorf("unable to get metrics for resource %s: %v", resource, err)
|
return 0, 0, 0, time.Time{}, fmt.Errorf("unable to get metrics for resource %s: %v", resource, err)
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ func (c *ReplicaCalculator) GetResourceReplicas(currentReplicas int32, targetUti
|
|||||||
readyPodCount, unreadyPods, missingPods, ignoredPods := groupPods(podList, metrics, resource, c.cpuInitializationPeriod, c.delayOfInitialReadinessStatus)
|
readyPodCount, unreadyPods, missingPods, ignoredPods := groupPods(podList, metrics, resource, c.cpuInitializationPeriod, c.delayOfInitialReadinessStatus)
|
||||||
removeMetricsForPods(metrics, ignoredPods)
|
removeMetricsForPods(metrics, ignoredPods)
|
||||||
removeMetricsForPods(metrics, unreadyPods)
|
removeMetricsForPods(metrics, unreadyPods)
|
||||||
requests, err := calculatePodRequests(podList, resource)
|
requests, err := calculatePodRequests(podList, container, resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, 0, time.Time{}, err
|
return 0, 0, 0, time.Time{}, err
|
||||||
}
|
}
|
||||||
@ -150,8 +150,8 @@ func (c *ReplicaCalculator) GetResourceReplicas(currentReplicas int32, targetUti
|
|||||||
|
|
||||||
// GetRawResourceReplicas calculates the desired replica count based on a target resource utilization (as a raw milli-value)
|
// GetRawResourceReplicas calculates the desired replica count based on a target resource utilization (as a raw milli-value)
|
||||||
// for pods matching the given selector in the given namespace, and the current replica count
|
// for pods matching the given selector in the given namespace, and the current replica count
|
||||||
func (c *ReplicaCalculator) GetRawResourceReplicas(currentReplicas int32, targetUtilization int64, resource v1.ResourceName, namespace string, selector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
func (c *ReplicaCalculator) GetRawResourceReplicas(currentReplicas int32, targetUtilization int64, resource v1.ResourceName, namespace string, selector labels.Selector, container string) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
|
||||||
metrics, timestamp, err := c.metricsClient.GetResourceMetric(resource, namespace, selector)
|
metrics, timestamp, err := c.metricsClient.GetResourceMetric(resource, namespace, selector, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, time.Time{}, fmt.Errorf("unable to get metrics for resource %s: %v", resource, err)
|
return 0, 0, time.Time{}, fmt.Errorf("unable to get metrics for resource %s: %v", resource, err)
|
||||||
}
|
}
|
||||||
@ -414,15 +414,17 @@ func groupPods(pods []*v1.Pod, metrics metricsclient.PodMetricsInfo, resource v1
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculatePodRequests(pods []*v1.Pod, resource v1.ResourceName) (map[string]int64, error) {
|
func calculatePodRequests(pods []*v1.Pod, container string, resource v1.ResourceName) (map[string]int64, error) {
|
||||||
requests := make(map[string]int64, len(pods))
|
requests := make(map[string]int64, len(pods))
|
||||||
for _, pod := range pods {
|
for _, pod := range pods {
|
||||||
podSum := int64(0)
|
podSum := int64(0)
|
||||||
for _, container := range pod.Spec.Containers {
|
for _, c := range pod.Spec.Containers {
|
||||||
if containerRequest, ok := container.Resources.Requests[resource]; ok {
|
if container == "" || container == c.Name {
|
||||||
podSum += containerRequest.MilliValue()
|
if containerRequest, ok := c.Resources.Requests[resource]; ok {
|
||||||
} else {
|
podSum += containerRequest.MilliValue()
|
||||||
return nil, fmt.Errorf("missing request for %s", resource)
|
} else {
|
||||||
|
return nil, fmt.Errorf("missing request for %s", resource)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requests[pod.Name] = podSum
|
requests[pod.Name] = podSum
|
||||||
|
@ -52,7 +52,7 @@ import (
|
|||||||
type resourceInfo struct {
|
type resourceInfo struct {
|
||||||
name v1.ResourceName
|
name v1.ResourceName
|
||||||
requests []resource.Quantity
|
requests []resource.Quantity
|
||||||
levels []int64
|
levels [][]int64
|
||||||
// only applies to pod names returned from "heapster"
|
// only applies to pod names returned from "heapster"
|
||||||
podNames []string
|
podNames []string
|
||||||
|
|
||||||
@ -93,6 +93,7 @@ type replicaCalcTestCase struct {
|
|||||||
resource *resourceInfo
|
resource *resourceInfo
|
||||||
metric *metricInfo
|
metric *metricInfo
|
||||||
metricLabelSelector labels.Selector
|
metricLabelSelector labels.Selector
|
||||||
|
container string
|
||||||
|
|
||||||
podReadiness []v1.ConditionStatus
|
podReadiness []v1.ConditionStatus
|
||||||
podStartTime []metav1.Time
|
podStartTime []metav1.Time
|
||||||
@ -152,7 +153,7 @@ func (tc *replicaCalcTestCase) prepareTestClientSet() *fake.Clientset {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
Containers: []v1.Container{{}, {}},
|
Containers: []v1.Container{{Name: "container1"}, {Name: "container2"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if podDeletionTimestamp {
|
if podDeletionTimestamp {
|
||||||
@ -202,13 +203,11 @@ func (tc *replicaCalcTestCase) prepareTestMetricsClient() *metricsfake.Clientset
|
|||||||
Containers: make([]metricsapi.ContainerMetrics, numContainersPerPod),
|
Containers: make([]metricsapi.ContainerMetrics, numContainersPerPod),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < numContainersPerPod; i++ {
|
for i, m := range resValue {
|
||||||
podMetric.Containers[i] = metricsapi.ContainerMetrics{
|
podMetric.Containers[i] = metricsapi.ContainerMetrics{
|
||||||
Name: fmt.Sprintf("container%v", i),
|
Name: fmt.Sprintf("container%v", i+1),
|
||||||
Usage: v1.ResourceList{
|
Usage: v1.ResourceList{
|
||||||
v1.ResourceName(tc.resource.name): *resource.NewMilliQuantity(
|
tc.resource.name: *resource.NewMilliQuantity(m, resource.DecimalSI),
|
||||||
int64(resValue),
|
|
||||||
resource.DecimalSI),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,7 +361,7 @@ func (tc *replicaCalcTestCase) runTest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tc.resource != nil {
|
if tc.resource != nil {
|
||||||
outReplicas, outUtilization, outRawValue, outTimestamp, err := replicaCalc.GetResourceReplicas(tc.currentReplicas, tc.resource.targetUtilization, tc.resource.name, testNamespace, selector)
|
outReplicas, outUtilization, outRawValue, outTimestamp, err := replicaCalc.GetResourceReplicas(tc.currentReplicas, tc.resource.targetUtilization, tc.resource.name, testNamespace, selector, tc.container)
|
||||||
|
|
||||||
if tc.expectedError != nil {
|
if tc.expectedError != nil {
|
||||||
require.Error(t, err, "there should be an error calculating the replica count")
|
require.Error(t, err, "there should be an error calculating the replica count")
|
||||||
@ -424,7 +423,16 @@ func (tc *replicaCalcTestCase) runTest(t *testing.T) {
|
|||||||
assert.Equal(t, tc.metric.expectedUtilization, outUtilization, "utilization should be as expected")
|
assert.Equal(t, tc.metric.expectedUtilization, outUtilization, "utilization should be as expected")
|
||||||
assert.True(t, tc.timestamp.Equal(outTimestamp), "timestamp should be as expected")
|
assert.True(t, tc.timestamp.Equal(outTimestamp), "timestamp should be as expected")
|
||||||
}
|
}
|
||||||
|
func makePodMetricLevels(containerMetric ...int64) [][]int64 {
|
||||||
|
metrics := make([][]int64, len(containerMetric))
|
||||||
|
for i := 0; i < len(containerMetric); i++ {
|
||||||
|
metrics[i] = make([]int64, numContainersPerPod)
|
||||||
|
for j := 0; j < numContainersPerPod; j++ {
|
||||||
|
metrics[i][j] = containerMetric[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return metrics
|
||||||
|
}
|
||||||
func TestReplicaCalcDisjointResourcesMetrics(t *testing.T) {
|
func TestReplicaCalcDisjointResourcesMetrics(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 1,
|
currentReplicas: 1,
|
||||||
@ -432,7 +440,7 @@ func TestReplicaCalcDisjointResourcesMetrics(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0")},
|
||||||
levels: []int64{100},
|
levels: makePodMetricLevels(100),
|
||||||
podNames: []string{"an-older-pod-name"},
|
podNames: []string{"an-older-pod-name"},
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
@ -441,6 +449,20 @@ func TestReplicaCalcDisjointResourcesMetrics(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcMissingContainerMetricError(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 1,
|
||||||
|
expectedError: fmt.Errorf("container container2 not present in metrics for pod test-namespace/test-pod-0"),
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{0}},
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleUp(t *testing.T) {
|
func TestReplicaCalcScaleUp(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 3,
|
currentReplicas: 3,
|
||||||
@ -448,7 +470,7 @@ func TestReplicaCalcScaleUp(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{300, 500, 700},
|
levels: makePodMetricLevels(300, 500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 50,
|
expectedUtilization: 50,
|
||||||
@ -458,6 +480,24 @@ func TestReplicaCalcScaleUp(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcContainerScaleUp(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 3,
|
||||||
|
expectedReplicas: 5,
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{1000, 300}, {1000, 500}, {1000, 700}},
|
||||||
|
|
||||||
|
targetUtilization: 30,
|
||||||
|
expectedUtilization: 50,
|
||||||
|
expectedValue: 500,
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleUpUnreadyLessScale(t *testing.T) {
|
func TestReplicaCalcScaleUpUnreadyLessScale(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 3,
|
currentReplicas: 3,
|
||||||
@ -466,7 +506,7 @@ func TestReplicaCalcScaleUpUnreadyLessScale(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{300, 500, 700},
|
levels: makePodMetricLevels(300, 500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 60,
|
expectedUtilization: 60,
|
||||||
@ -476,6 +516,25 @@ func TestReplicaCalcScaleUpUnreadyLessScale(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcScaleUpContainerHotCpuLessScale(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 3,
|
||||||
|
expectedReplicas: 4,
|
||||||
|
podStartTime: []metav1.Time{hotCPUCreationTime(), coolCPUCreationTime(), coolCPUCreationTime()},
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{0, 300}, {0, 500}, {0, 700}},
|
||||||
|
|
||||||
|
targetUtilization: 30,
|
||||||
|
expectedUtilization: 60,
|
||||||
|
expectedValue: 600,
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleUpHotCpuLessScale(t *testing.T) {
|
func TestReplicaCalcScaleUpHotCpuLessScale(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 3,
|
currentReplicas: 3,
|
||||||
@ -484,7 +543,7 @@ func TestReplicaCalcScaleUpHotCpuLessScale(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{300, 500, 700},
|
levels: makePodMetricLevels(300, 500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 60,
|
expectedUtilization: 60,
|
||||||
@ -502,7 +561,7 @@ func TestReplicaCalcScaleUpUnreadyNoScale(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{400, 500, 700},
|
levels: makePodMetricLevels(400, 500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 40,
|
expectedUtilization: 40,
|
||||||
@ -521,7 +580,7 @@ func TestReplicaCalcScaleHotCpuNoScale(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{400, 500, 700},
|
levels: makePodMetricLevels(400, 500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 40,
|
expectedUtilization: 40,
|
||||||
@ -540,7 +599,7 @@ func TestReplicaCalcScaleUpIgnoresFailedPods(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{500, 700},
|
levels: makePodMetricLevels(500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 60,
|
expectedUtilization: 60,
|
||||||
@ -550,6 +609,26 @@ func TestReplicaCalcScaleUpIgnoresFailedPods(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcScaleUpContainerIgnoresFailedPods(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 2,
|
||||||
|
expectedReplicas: 4,
|
||||||
|
podReadiness: []v1.ConditionStatus{v1.ConditionTrue, v1.ConditionTrue, v1.ConditionFalse, v1.ConditionFalse},
|
||||||
|
podPhase: []v1.PodPhase{v1.PodRunning, v1.PodRunning, v1.PodFailed, v1.PodFailed},
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{1000, 500}, {9000, 700}},
|
||||||
|
|
||||||
|
targetUtilization: 30,
|
||||||
|
expectedUtilization: 60,
|
||||||
|
expectedValue: 600,
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleUpIgnoresDeletionPods(t *testing.T) {
|
func TestReplicaCalcScaleUpIgnoresDeletionPods(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
@ -560,7 +639,7 @@ func TestReplicaCalcScaleUpIgnoresDeletionPods(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{500, 700},
|
levels: makePodMetricLevels(500, 700),
|
||||||
|
|
||||||
targetUtilization: 30,
|
targetUtilization: 30,
|
||||||
expectedUtilization: 60,
|
expectedUtilization: 60,
|
||||||
@ -570,6 +649,27 @@ func TestReplicaCalcScaleUpIgnoresDeletionPods(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcScaleUpContainerIgnoresDeletionPods(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 2,
|
||||||
|
expectedReplicas: 4,
|
||||||
|
podReadiness: []v1.ConditionStatus{v1.ConditionTrue, v1.ConditionTrue, v1.ConditionFalse, v1.ConditionFalse},
|
||||||
|
podPhase: []v1.PodPhase{v1.PodRunning, v1.PodRunning, v1.PodRunning, v1.PodRunning},
|
||||||
|
podDeletionTimestamp: []bool{false, false, true, true},
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: makePodMetricLevels(500, 700), // TODO: This test is broken and works only because of missing metrics
|
||||||
|
|
||||||
|
targetUtilization: 30,
|
||||||
|
expectedUtilization: 60,
|
||||||
|
expectedValue: 600,
|
||||||
|
},
|
||||||
|
container: "container1",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleUpCM(t *testing.T) {
|
func TestReplicaCalcScaleUpCM(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 3,
|
currentReplicas: 3,
|
||||||
@ -749,7 +849,7 @@ func TestReplicaCalcScaleDown(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 300, 500, 250, 250},
|
levels: makePodMetricLevels(100, 300, 500, 250, 250),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 28,
|
expectedUtilization: 28,
|
||||||
@ -759,6 +859,24 @@ func TestReplicaCalcScaleDown(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcContainerScaleDown(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 5,
|
||||||
|
expectedReplicas: 3,
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{1000, 100}, {1000, 300}, {1000, 500}, {1000, 250}, {1000, 250}},
|
||||||
|
|
||||||
|
targetUtilization: 50,
|
||||||
|
expectedUtilization: 28,
|
||||||
|
expectedValue: 280,
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleDownCM(t *testing.T) {
|
func TestReplicaCalcScaleDownCM(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 5,
|
currentReplicas: 5,
|
||||||
@ -845,7 +963,7 @@ func TestReplicaCalcScaleDownPerPodCMExternal(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleDownIncludeUnreadyPods(t *testing.T) {
|
func TestReplicaCalcScaleDownExcludeUnreadyPods(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 5,
|
currentReplicas: 5,
|
||||||
expectedReplicas: 2,
|
expectedReplicas: 2,
|
||||||
@ -853,7 +971,7 @@ func TestReplicaCalcScaleDownIncludeUnreadyPods(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 300, 500, 250, 250},
|
levels: makePodMetricLevels(100, 300, 500, 250, 250),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 30,
|
expectedUtilization: 30,
|
||||||
@ -863,6 +981,25 @@ func TestReplicaCalcScaleDownIncludeUnreadyPods(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcScaleDownContainerExcludeUnreadyPods(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 5,
|
||||||
|
expectedReplicas: 2,
|
||||||
|
podReadiness: []v1.ConditionStatus{v1.ConditionTrue, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionFalse, v1.ConditionFalse},
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{1000, 100}, {1000, 300}, {1000, 500}, {1000, 250}, {1000, 250}},
|
||||||
|
|
||||||
|
targetUtilization: 50,
|
||||||
|
expectedUtilization: 30,
|
||||||
|
expectedValue: 300,
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleDownExcludeUnscheduledPods(t *testing.T) {
|
func TestReplicaCalcScaleDownExcludeUnscheduledPods(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 5,
|
currentReplicas: 5,
|
||||||
@ -872,7 +1009,7 @@ func TestReplicaCalcScaleDownExcludeUnscheduledPods(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100},
|
levels: makePodMetricLevels(100),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 10,
|
expectedUtilization: 10,
|
||||||
@ -882,6 +1019,26 @@ func TestReplicaCalcScaleDownExcludeUnscheduledPods(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcScaleDownContainerExcludeUnscheduledPods(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 5,
|
||||||
|
expectedReplicas: 1,
|
||||||
|
podReadiness: []v1.ConditionStatus{v1.ConditionTrue, v1.ConditionFalse, v1.ConditionFalse, v1.ConditionFalse, v1.ConditionFalse},
|
||||||
|
podPhase: []v1.PodPhase{v1.PodRunning, v1.PodPending, v1.PodPending, v1.PodPending, v1.PodPending},
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{1000, 100}, {1000, 300}, {1000, 500}, {1000, 250}, {1000, 250}},
|
||||||
|
|
||||||
|
targetUtilization: 50,
|
||||||
|
expectedUtilization: 10,
|
||||||
|
expectedValue: 100,
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleDownIgnoreHotCpuPods(t *testing.T) {
|
func TestReplicaCalcScaleDownIgnoreHotCpuPods(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 5,
|
currentReplicas: 5,
|
||||||
@ -890,7 +1047,7 @@ func TestReplicaCalcScaleDownIgnoreHotCpuPods(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 300, 500, 250, 250},
|
levels: makePodMetricLevels(100, 300, 500, 250, 250),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 30,
|
expectedUtilization: 30,
|
||||||
@ -900,6 +1057,25 @@ func TestReplicaCalcScaleDownIgnoreHotCpuPods(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcScaleDownContainerIgnoreHotCpuPods(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 5,
|
||||||
|
expectedReplicas: 2,
|
||||||
|
podStartTime: []metav1.Time{coolCPUCreationTime(), coolCPUCreationTime(), coolCPUCreationTime(), hotCPUCreationTime(), hotCPUCreationTime()},
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{1000, 100}, {1000, 300}, {1000, 500}, {1000, 1000}, {1000, 1000}},
|
||||||
|
|
||||||
|
targetUtilization: 50,
|
||||||
|
expectedUtilization: 30,
|
||||||
|
expectedValue: 300,
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleDownIgnoresFailedPods(t *testing.T) {
|
func TestReplicaCalcScaleDownIgnoresFailedPods(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 5,
|
currentReplicas: 5,
|
||||||
@ -909,7 +1085,7 @@ func TestReplicaCalcScaleDownIgnoresFailedPods(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 300, 500, 250, 250},
|
levels: makePodMetricLevels(100, 300, 500, 250, 250),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 28,
|
expectedUtilization: 28,
|
||||||
@ -919,6 +1095,26 @@ func TestReplicaCalcScaleDownIgnoresFailedPods(t *testing.T) {
|
|||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplicaCalcScaleDownContainerIgnoresFailedPods(t *testing.T) {
|
||||||
|
tc := replicaCalcTestCase{
|
||||||
|
currentReplicas: 5,
|
||||||
|
expectedReplicas: 3,
|
||||||
|
podReadiness: []v1.ConditionStatus{v1.ConditionTrue, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionFalse, v1.ConditionFalse},
|
||||||
|
podPhase: []v1.PodPhase{v1.PodRunning, v1.PodRunning, v1.PodRunning, v1.PodRunning, v1.PodRunning, v1.PodFailed, v1.PodFailed},
|
||||||
|
resource: &resourceInfo{
|
||||||
|
name: v1.ResourceCPU,
|
||||||
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
|
levels: [][]int64{{1000, 100}, {1000, 300}, {1000, 500}, {1000, 250}, {1000, 250}}, //TODO: Test is broken
|
||||||
|
|
||||||
|
targetUtilization: 50,
|
||||||
|
expectedUtilization: 28,
|
||||||
|
expectedValue: 280,
|
||||||
|
},
|
||||||
|
container: "container2",
|
||||||
|
}
|
||||||
|
tc.runTest(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplicaCalcScaleDownIgnoresDeletionPods(t *testing.T) {
|
func TestReplicaCalcScaleDownIgnoresDeletionPods(t *testing.T) {
|
||||||
tc := replicaCalcTestCase{
|
tc := replicaCalcTestCase{
|
||||||
currentReplicas: 5,
|
currentReplicas: 5,
|
||||||
@ -929,7 +1125,7 @@ func TestReplicaCalcScaleDownIgnoresDeletionPods(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 300, 500, 250, 250},
|
levels: makePodMetricLevels(100, 300, 500, 250, 250),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 28,
|
expectedUtilization: 28,
|
||||||
@ -950,12 +1146,13 @@ func TestReplicaCalcScaleDownIgnoresDeletionPods_StillRunning(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 300, 500, 250, 250, 0, 0},
|
levels: [][]int64{{1000, 100}, {1000, 300}, {1000, 500}, {1000, 250}, {1000, 250}},
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 28,
|
expectedUtilization: 28,
|
||||||
expectedValue: numContainersPerPod * 280,
|
expectedValue: 280,
|
||||||
},
|
},
|
||||||
|
container: "container2",
|
||||||
}
|
}
|
||||||
tc.runTest(t)
|
tc.runTest(t)
|
||||||
}
|
}
|
||||||
@ -967,7 +1164,7 @@ func TestReplicaCalcTolerance(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")},
|
requests: []resource.Quantity{resource.MustParse("0.9"), resource.MustParse("1.0"), resource.MustParse("1.1")},
|
||||||
levels: []int64{1010, 1030, 1020},
|
levels: makePodMetricLevels(1010, 1030, 1020),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 102,
|
expectedUtilization: 102,
|
||||||
@ -1070,7 +1267,7 @@ func TestReplicaCalcSuperfluousMetrics(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{4000, 9500, 3000, 7000, 3200, 2000},
|
levels: makePodMetricLevels(4000, 9500, 3000, 7000, 3200, 2000),
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 587,
|
expectedUtilization: 587,
|
||||||
expectedValue: numContainersPerPod * 5875,
|
expectedValue: numContainersPerPod * 5875,
|
||||||
@ -1086,7 +1283,7 @@ func TestReplicaCalcMissingMetrics(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{400, 95},
|
levels: makePodMetricLevels(400, 95),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 24,
|
expectedUtilization: 24,
|
||||||
@ -1103,7 +1300,7 @@ func TestReplicaCalcEmptyMetrics(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{},
|
levels: makePodMetricLevels(),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
},
|
},
|
||||||
@ -1118,7 +1315,7 @@ func TestReplicaCalcEmptyCPURequest(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{},
|
requests: []resource.Quantity{},
|
||||||
levels: []int64{200},
|
levels: makePodMetricLevels(200),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
},
|
},
|
||||||
@ -1133,7 +1330,7 @@ func TestReplicaCalcMissingMetricsNoChangeEq(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{1000},
|
levels: makePodMetricLevels(1000),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 100,
|
expectedUtilization: 100,
|
||||||
@ -1150,7 +1347,7 @@ func TestReplicaCalcMissingMetricsNoChangeGt(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{1900},
|
levels: makePodMetricLevels(1900),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 190,
|
expectedUtilization: 190,
|
||||||
@ -1167,7 +1364,7 @@ func TestReplicaCalcMissingMetricsNoChangeLt(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{600},
|
levels: makePodMetricLevels(600),
|
||||||
|
|
||||||
targetUtilization: 100,
|
targetUtilization: 100,
|
||||||
expectedUtilization: 60,
|
expectedUtilization: 60,
|
||||||
@ -1185,7 +1382,7 @@ func TestReplicaCalcMissingMetricsUnreadyChange(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 450},
|
levels: makePodMetricLevels(100, 450),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 45,
|
expectedUtilization: 45,
|
||||||
@ -1203,7 +1400,7 @@ func TestReplicaCalcMissingMetricsHotCpuNoChange(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 450},
|
levels: makePodMetricLevels(100, 450),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 45,
|
expectedUtilization: 45,
|
||||||
@ -1221,7 +1418,7 @@ func TestReplicaCalcMissingMetricsUnreadyScaleUp(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 2000},
|
levels: makePodMetricLevels(100, 2000),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 200,
|
expectedUtilization: 200,
|
||||||
@ -1240,7 +1437,7 @@ func TestReplicaCalcMissingMetricsHotCpuScaleUp(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 2000},
|
levels: makePodMetricLevels(100, 2000),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 200,
|
expectedUtilization: 200,
|
||||||
@ -1258,7 +1455,7 @@ func TestReplicaCalcMissingMetricsUnreadyScaleDown(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 100, 100},
|
levels: makePodMetricLevels(100, 100, 100),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 10,
|
expectedUtilization: 10,
|
||||||
@ -1276,7 +1473,7 @@ func TestReplicaCalcDuringRollingUpdateWithMaxSurge(t *testing.T) {
|
|||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
requests: []resource.Quantity{resource.MustParse("1.0"), resource.MustParse("1.0"), resource.MustParse("1.0")},
|
||||||
levels: []int64{100, 100},
|
levels: makePodMetricLevels(100, 100),
|
||||||
|
|
||||||
targetUtilization: 50,
|
targetUtilization: 50,
|
||||||
expectedUtilization: 10,
|
expectedUtilization: 10,
|
||||||
@ -1315,18 +1512,18 @@ func TestReplicaCalcComputedToleranceAlgImplementation(t *testing.T) {
|
|||||||
expectedReplicas: finalPods,
|
expectedReplicas: finalPods,
|
||||||
resource: &resourceInfo{
|
resource: &resourceInfo{
|
||||||
name: v1.ResourceCPU,
|
name: v1.ResourceCPU,
|
||||||
levels: []int64{
|
levels: makePodMetricLevels(
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
totalUsedCPUOfAllPods / 10,
|
totalUsedCPUOfAllPods/10,
|
||||||
},
|
),
|
||||||
requests: []resource.Quantity{
|
requests: []resource.Quantity{
|
||||||
resource.MustParse(fmt.Sprint(perPodRequested+100) + "m"),
|
resource.MustParse(fmt.Sprint(perPodRequested+100) + "m"),
|
||||||
resource.MustParse(fmt.Sprint(perPodRequested-100) + "m"),
|
resource.MustParse(fmt.Sprint(perPodRequested-100) + "m"),
|
||||||
|
@ -642,6 +642,13 @@ const (
|
|||||||
//
|
//
|
||||||
// Disables Accelerator Metrics Collected by Kubelet
|
// Disables Accelerator Metrics Collected by Kubelet
|
||||||
DisableAcceleratorUsageMetrics featuregate.Feature = "DisableAcceleratorUsageMetrics"
|
DisableAcceleratorUsageMetrics featuregate.Feature = "DisableAcceleratorUsageMetrics"
|
||||||
|
|
||||||
|
// owner: @arjunrn @mwielgus @josephburnett
|
||||||
|
// alpha: v1.20
|
||||||
|
//
|
||||||
|
// Add support for the HPA to scale based on metrics from individual containers
|
||||||
|
// in target pods
|
||||||
|
HPAContainerMetrics featuregate.Feature = "HPAContainerMetrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -739,6 +746,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
WinOverlay: {Default: true, PreRelease: featuregate.Beta},
|
WinOverlay: {Default: true, PreRelease: featuregate.Beta},
|
||||||
WinDSR: {Default: false, PreRelease: featuregate.Alpha},
|
WinDSR: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
DisableAcceleratorUsageMetrics: {Default: true, PreRelease: featuregate.Beta},
|
DisableAcceleratorUsageMetrics: {Default: true, PreRelease: featuregate.Beta},
|
||||||
|
HPAContainerMetrics: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
|
||||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||||
// unintentionally on either side:
|
// unintentionally on either side:
|
||||||
|
@ -2042,6 +2042,25 @@ func formatHPAMetrics(specs []autoscaling.MetricSpec, statuses []autoscaling.Met
|
|||||||
}
|
}
|
||||||
list = append(list, fmt.Sprintf("%s/%s", current, target))
|
list = append(list, fmt.Sprintf("%s/%s", current, target))
|
||||||
}
|
}
|
||||||
|
case autoscaling.ContainerResourceMetricSourceType:
|
||||||
|
if spec.ContainerResource.Target.AverageValue != nil {
|
||||||
|
current := "<unknown>"
|
||||||
|
if len(statuses) > i && statuses[i].ContainerResource != nil {
|
||||||
|
current = statuses[i].ContainerResource.Current.AverageValue.String()
|
||||||
|
}
|
||||||
|
list = append(list, fmt.Sprintf("%s/%s", current, spec.ContainerResource.Target.AverageValue.String()))
|
||||||
|
} else {
|
||||||
|
current := "<unknown>"
|
||||||
|
if len(statuses) > i && statuses[i].ContainerResource != nil && statuses[i].ContainerResource.Current.AverageUtilization != nil {
|
||||||
|
current = fmt.Sprintf("%d%%", *statuses[i].ContainerResource.Current.AverageUtilization)
|
||||||
|
}
|
||||||
|
|
||||||
|
target := "<auto>"
|
||||||
|
if spec.ContainerResource.Target.AverageUtilization != nil {
|
||||||
|
target = fmt.Sprintf("%d%%", *spec.ContainerResource.Target.AverageUtilization)
|
||||||
|
}
|
||||||
|
list = append(list, fmt.Sprintf("%s/%s", current, target))
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
list = append(list, "<unknown type>")
|
list = append(list, "<unknown type>")
|
||||||
}
|
}
|
||||||
|
@ -2813,6 +2813,161 @@ func TestPrintHPA(t *testing.T) {
|
|||||||
// Columns: Name, Reference, Targets, MinPods, MaxPods, Replicas, Age
|
// Columns: Name, Reference, Targets, MinPods, MaxPods, Replicas, Age
|
||||||
expected: []metav1.TableRow{{Cells: []interface{}{"some-hpa", "ReplicationController/some-rc", "50%/80%", "2", int64(10), int64(4), "<unknown>"}}},
|
expected: []metav1.TableRow{{Cells: []interface{}{"some-hpa", "ReplicationController/some-rc", "50%/80%", "2", int64(10), int64(4), "<unknown>"}}},
|
||||||
},
|
},
|
||||||
|
// container resource source type, targetVal (no current)
|
||||||
|
{
|
||||||
|
hpa: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "some-hpa"},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||||
|
Name: "some-rc",
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
},
|
||||||
|
MinReplicas: &minReplicasVal,
|
||||||
|
MaxReplicas: 10,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.AverageValueMetricType,
|
||||||
|
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscaling.HorizontalPodAutoscalerStatus{
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
DesiredReplicas: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, Reference, Targets, MinPods, MaxPods, Replicas, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"some-hpa", "ReplicationController/some-rc", "<unknown>/100m", "2", int64(10), int64(4), "<unknown>"}}},
|
||||||
|
},
|
||||||
|
// container resource source type, targetVal
|
||||||
|
{
|
||||||
|
hpa: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "some-hpa"},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||||
|
Name: "some-rc",
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
},
|
||||||
|
MinReplicas: &minReplicasVal,
|
||||||
|
MaxReplicas: 10,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.AverageValueMetricType,
|
||||||
|
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscaling.HorizontalPodAutoscalerStatus{
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
DesiredReplicas: 5,
|
||||||
|
CurrentMetrics: []autoscaling.MetricStatus{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricStatus{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Current: autoscaling.MetricValueStatus{
|
||||||
|
AverageValue: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, Reference, Targets, MinPods, MaxPods, Replicas, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"some-hpa", "ReplicationController/some-rc", "50m/100m", "2", int64(10), int64(4), "<unknown>"}}},
|
||||||
|
},
|
||||||
|
// container resource source type, targetUtil (no current)
|
||||||
|
{
|
||||||
|
hpa: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "some-hpa"},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||||
|
Name: "some-rc",
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
},
|
||||||
|
MinReplicas: &minReplicasVal,
|
||||||
|
MaxReplicas: 10,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: &targetUtilizationVal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscaling.HorizontalPodAutoscalerStatus{
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
DesiredReplicas: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, Reference, Targets, MinPods, MaxPods, Replicas, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"some-hpa", "ReplicationController/some-rc", "<unknown>/80%", "2", int64(10), int64(4), "<unknown>"}}},
|
||||||
|
},
|
||||||
|
// container resource source type, targetUtil
|
||||||
|
{
|
||||||
|
hpa: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "some-hpa"},
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||||
|
Name: "some-rc",
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
},
|
||||||
|
MinReplicas: &minReplicasVal,
|
||||||
|
MaxReplicas: 10,
|
||||||
|
Metrics: []autoscaling.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: &targetUtilizationVal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscaling.HorizontalPodAutoscalerStatus{
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
DesiredReplicas: 5,
|
||||||
|
CurrentMetrics: []autoscaling.MetricStatus{
|
||||||
|
{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricStatus{
|
||||||
|
Name: api.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Current: autoscaling.MetricValueStatus{
|
||||||
|
AverageUtilization: ¤tUtilizationVal,
|
||||||
|
AverageValue: resource.NewMilliQuantity(40, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, Reference, Targets, MinPods, MaxPods, Replicas, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"some-hpa", "ReplicationController/some-rc", "50%/80%", "2", int64(10), int64(4), "<unknown>"}}},
|
||||||
|
},
|
||||||
// multiple specs
|
// multiple specs
|
||||||
{
|
{
|
||||||
hpa: autoscaling.HorizontalPodAutoscaler{
|
hpa: autoscaling.HorizontalPodAutoscaler{
|
||||||
|
@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"])
|
|||||||
load(
|
load(
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
"go_library",
|
"go_library",
|
||||||
|
"go_test",
|
||||||
)
|
)
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
@ -16,9 +17,11 @@ go_library(
|
|||||||
"//pkg/api/legacyscheme:go_default_library",
|
"//pkg/api/legacyscheme:go_default_library",
|
||||||
"//pkg/apis/autoscaling:go_default_library",
|
"//pkg/apis/autoscaling:go_default_library",
|
||||||
"//pkg/apis/autoscaling/validation:go_default_library",
|
"//pkg/apis/autoscaling/validation:go_default_library",
|
||||||
|
"//pkg/features:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,3 +40,17 @@ filegroup(
|
|||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["strategy_test.go"],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//pkg/apis/autoscaling:go_default_library",
|
||||||
|
"//pkg/apis/core:go_default_library",
|
||||||
|
"//pkg/features:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
|
||||||
|
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@ -22,9 +22,11 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/apiserver/pkg/storage/names"
|
"k8s.io/apiserver/pkg/storage/names"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||||
"k8s.io/kubernetes/pkg/apis/autoscaling/validation"
|
"k8s.io/kubernetes/pkg/apis/autoscaling/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
)
|
)
|
||||||
|
|
||||||
// autoscalerStrategy implements behavior for HorizontalPodAutoscalers
|
// autoscalerStrategy implements behavior for HorizontalPodAutoscalers
|
||||||
@ -48,6 +50,10 @@ func (autoscalerStrategy) PrepareForCreate(ctx context.Context, obj runtime.Obje
|
|||||||
|
|
||||||
// create cannot set status
|
// create cannot set status
|
||||||
newHPA.Status = autoscaling.HorizontalPodAutoscalerStatus{}
|
newHPA.Status = autoscaling.HorizontalPodAutoscalerStatus{}
|
||||||
|
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(features.HPAContainerMetrics) {
|
||||||
|
dropContainerMetricSources(newHPA.Spec.Metrics)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates a new autoscaler.
|
// Validate validates a new autoscaler.
|
||||||
@ -69,10 +75,30 @@ func (autoscalerStrategy) AllowCreateOnUpdate() bool {
|
|||||||
func (autoscalerStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
|
func (autoscalerStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
|
||||||
newHPA := obj.(*autoscaling.HorizontalPodAutoscaler)
|
newHPA := obj.(*autoscaling.HorizontalPodAutoscaler)
|
||||||
oldHPA := old.(*autoscaling.HorizontalPodAutoscaler)
|
oldHPA := old.(*autoscaling.HorizontalPodAutoscaler)
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(features.HPAContainerMetrics) && !hasContainerMetricSources(oldHPA) {
|
||||||
|
dropContainerMetricSources(newHPA.Spec.Metrics)
|
||||||
|
}
|
||||||
// Update is not allowed to set status
|
// Update is not allowed to set status
|
||||||
newHPA.Status = oldHPA.Status
|
newHPA.Status = oldHPA.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dropContainerMetricSources ensures all container resource metric sources are nil
|
||||||
|
func dropContainerMetricSources(metrics []autoscaling.MetricSpec) {
|
||||||
|
for i := range metrics {
|
||||||
|
metrics[i].ContainerResource = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasContainerMetricSources returns true if the hpa has any container resource metric sources
|
||||||
|
func hasContainerMetricSources(hpa *autoscaling.HorizontalPodAutoscaler) bool {
|
||||||
|
for i := range hpa.Spec.Metrics {
|
||||||
|
if hpa.Spec.Metrics[i].ContainerResource != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ValidateUpdate is the default update validation for an end user.
|
// ValidateUpdate is the default update validation for an end user.
|
||||||
func (autoscalerStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
func (autoscalerStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||||
return validation.ValidateHorizontalPodAutoscalerUpdate(obj.(*autoscaling.HorizontalPodAutoscaler), old.(*autoscaling.HorizontalPodAutoscaler))
|
return validation.ValidateHorizontalPodAutoscalerUpdate(obj.(*autoscaling.HorizontalPodAutoscaler), old.(*autoscaling.HorizontalPodAutoscaler))
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 The Kubernetes Authors.
|
||||||
|
|
||||||
|
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 horizontalpodautoscaler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/core"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
|
"k8s.io/utils/pointer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeTestContainerMetricsHPA(hasContainerMetric bool) *autoscaling.HorizontalPodAutoscaler {
|
||||||
|
testHPA := &autoscaling.HorizontalPodAutoscaler{
|
||||||
|
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||||
|
Metrics: []autoscaling.MetricSpec{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if hasContainerMetric {
|
||||||
|
testHPA.Spec.Metrics = append(testHPA.Spec.Metrics, autoscaling.MetricSpec{
|
||||||
|
Type: autoscaling.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscaling.ContainerResourceMetricSource{
|
||||||
|
Name: core.ResourceCPU,
|
||||||
|
Container: "test-container",
|
||||||
|
Target: autoscaling.MetricTarget{
|
||||||
|
Type: autoscaling.UtilizationMetricType,
|
||||||
|
AverageUtilization: pointer.Int32Ptr(30),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return testHPA
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateWithFeatureEnabled(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAContainerMetrics, true)()
|
||||||
|
testHPA := makeTestContainerMetricsHPA(true)
|
||||||
|
Strategy.PrepareForCreate(context.Background(), testHPA)
|
||||||
|
if testHPA.Spec.Metrics[0].ContainerResource == nil {
|
||||||
|
t.Errorf("container metrics was set to nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateWithFeatureDisabled(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAContainerMetrics, false)()
|
||||||
|
testHPA := makeTestContainerMetricsHPA(true)
|
||||||
|
Strategy.PrepareForCreate(context.Background(), testHPA)
|
||||||
|
if testHPA.Spec.Metrics[0].ContainerResource != nil {
|
||||||
|
t.Errorf("container metrics is not nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAutoscalerStatusStrategy_PrepareForUpdate(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
featureEnabled bool
|
||||||
|
old bool
|
||||||
|
expectedNew bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "feature disabled with existing container metrics",
|
||||||
|
featureEnabled: false,
|
||||||
|
old: true,
|
||||||
|
expectedNew: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "feature enabled with no container metrics",
|
||||||
|
featureEnabled: true,
|
||||||
|
old: false,
|
||||||
|
expectedNew: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "feature enabled with existing container metrics",
|
||||||
|
featureEnabled: true,
|
||||||
|
old: true,
|
||||||
|
expectedNew: true,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAContainerMetrics, tc.featureEnabled)()
|
||||||
|
oldHPA := makeTestContainerMetricsHPA(tc.old)
|
||||||
|
newHPA := makeTestContainerMetricsHPA(true)
|
||||||
|
Strategy.PrepareForUpdate(context.Background(), newHPA, oldHPA)
|
||||||
|
if tc.expectedNew && newHPA.Spec.Metrics[0].ContainerResource == nil {
|
||||||
|
t.Errorf("container metric source is nil")
|
||||||
|
}
|
||||||
|
if !tc.expectedNew && newHPA.Spec.Metrics[0].ContainerResource != nil {
|
||||||
|
t.Errorf("container metric source is not nil")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
905
staging/src/k8s.io/api/autoscaling/v1/generated.pb.go
generated
905
staging/src/k8s.io/api/autoscaling/v1/generated.pb.go
generated
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,60 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
|
|||||||
// Package-wide variables from generator "generated".
|
// Package-wide variables from generator "generated".
|
||||||
option go_package = "v1";
|
option go_package = "v1";
|
||||||
|
|
||||||
|
// ContainerResourceMetricSource indicates how to scale on a resource metric known to
|
||||||
|
// Kubernetes, as specified in the requests and limits, describing a single container in
|
||||||
|
// each of the pods of the current scale target(e.g. CPU or memory). The values will be
|
||||||
|
// averaged together before being compared to the target. Such metrics are built into
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source. Only one "target" type
|
||||||
|
// should be set.
|
||||||
|
message ContainerResourceMetricSource {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
optional string name = 1;
|
||||||
|
|
||||||
|
// targetAverageUtilization is the target value of the average of the
|
||||||
|
// resource metric across all relevant pods, represented as a percentage of
|
||||||
|
// the requested value of the resource for the pods.
|
||||||
|
// +optional
|
||||||
|
optional int32 targetAverageUtilization = 2;
|
||||||
|
|
||||||
|
// targetAverageValue is the target value of the average of the
|
||||||
|
// resource metric across all relevant pods, as a raw value (instead of as
|
||||||
|
// a percentage of the request), similar to the "pods" metric source type.
|
||||||
|
// +optional
|
||||||
|
optional k8s.io.apimachinery.pkg.api.resource.Quantity targetAverageValue = 3;
|
||||||
|
|
||||||
|
// container is the name of the container in the pods of the scaling target.
|
||||||
|
optional string container = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricStatus indicates the current value of a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source.
|
||||||
|
message ContainerResourceMetricStatus {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
optional string name = 1;
|
||||||
|
|
||||||
|
// currentAverageUtilization is the current value of the average of the
|
||||||
|
// resource metric across all relevant pods, represented as a percentage of
|
||||||
|
// the requested value of the resource for the pods. It will only be
|
||||||
|
// present if `targetAverageValue` was set in the corresponding metric
|
||||||
|
// specification.
|
||||||
|
// +optional
|
||||||
|
optional int32 currentAverageUtilization = 2;
|
||||||
|
|
||||||
|
// currentAverageValue is the current value of the average of the
|
||||||
|
// resource metric across all relevant pods, as a raw value (instead of as
|
||||||
|
// a percentage of the request), similar to the "pods" metric source type.
|
||||||
|
// It will always be set, regardless of the corresponding metric specification.
|
||||||
|
optional k8s.io.apimachinery.pkg.api.resource.Quantity currentAverageValue = 3;
|
||||||
|
|
||||||
|
// container is the name of the container in the pods of the scaling taget
|
||||||
|
optional string container = 4;
|
||||||
|
}
|
||||||
|
|
||||||
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
|
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
|
||||||
message CrossVersionObjectReference {
|
message CrossVersionObjectReference {
|
||||||
// Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
|
// Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
|
||||||
@ -184,8 +238,10 @@ message HorizontalPodAutoscalerStatus {
|
|||||||
// MetricSpec specifies how to scale based on a single metric
|
// MetricSpec specifies how to scale based on a single metric
|
||||||
// (only `type` and one other matching field should be set at once).
|
// (only `type` and one other matching field should be set at once).
|
||||||
message MetricSpec {
|
message MetricSpec {
|
||||||
// type is the type of metric source. It should be one of "Object",
|
// type is the type of metric source. It should be one of "ContainerResource",
|
||||||
// "Pods" or "Resource", each mapping to a matching field in the object.
|
// "External", "Object", "Pods" or "Resource", each mapping to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
optional string type = 1;
|
optional string type = 1;
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -207,6 +263,15 @@ message MetricSpec {
|
|||||||
// +optional
|
// +optional
|
||||||
optional ResourceMetricSource resource = 4;
|
optional ResourceMetricSource resource = 4;
|
||||||
|
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod of the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.
|
||||||
|
// +optional
|
||||||
|
optional ContainerResourceMetricSource containerResource = 7;
|
||||||
|
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -218,8 +283,10 @@ message MetricSpec {
|
|||||||
|
|
||||||
// MetricStatus describes the last-read state of a single metric.
|
// MetricStatus describes the last-read state of a single metric.
|
||||||
message MetricStatus {
|
message MetricStatus {
|
||||||
// type is the type of metric source. It will be one of "Object",
|
// type is the type of metric source. It will be one of "ContainerResource",
|
||||||
// "Pods" or "Resource", each corresponds to a matching field in the object.
|
// "External", "Object", "Pods" or "Resource", each corresponds to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
optional string type = 1;
|
optional string type = 1;
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -241,6 +308,14 @@ message MetricStatus {
|
|||||||
// +optional
|
// +optional
|
||||||
optional ResourceMetricStatus resource = 4;
|
optional ResourceMetricStatus resource = 4;
|
||||||
|
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// +optional
|
||||||
|
optional ContainerResourceMetricStatus containerResource = 7;
|
||||||
|
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
|
@ -165,6 +165,12 @@ const (
|
|||||||
// Kubernetes, and have special scaling options on top of those available
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
// to normal per-pod metrics (the "pods" source).
|
// to normal per-pod metrics (the "pods" source).
|
||||||
ResourceMetricSourceType MetricSourceType = "Resource"
|
ResourceMetricSourceType MetricSourceType = "Resource"
|
||||||
|
// ContainerResourceMetricSourceType is a resource metric known to Kubernetes, as
|
||||||
|
// specified in requests and limits, describing a single container in each pod in the current
|
||||||
|
// scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics (the "pods" source).
|
||||||
|
ContainerResourceMetricSourceType MetricSourceType = "ContainerResource"
|
||||||
// ExternalMetricSourceType is a global metric that is not associated
|
// ExternalMetricSourceType is a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -176,8 +182,10 @@ const (
|
|||||||
// MetricSpec specifies how to scale based on a single metric
|
// MetricSpec specifies how to scale based on a single metric
|
||||||
// (only `type` and one other matching field should be set at once).
|
// (only `type` and one other matching field should be set at once).
|
||||||
type MetricSpec struct {
|
type MetricSpec struct {
|
||||||
// type is the type of metric source. It should be one of "Object",
|
// type is the type of metric source. It should be one of "ContainerResource",
|
||||||
// "Pods" or "Resource", each mapping to a matching field in the object.
|
// "External", "Object", "Pods" or "Resource", each mapping to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -196,6 +204,14 @@ type MetricSpec struct {
|
|||||||
// to normal per-pod metrics using the "pods" source.
|
// to normal per-pod metrics using the "pods" source.
|
||||||
// +optional
|
// +optional
|
||||||
Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod of the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.
|
||||||
|
// +optional
|
||||||
|
ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"`
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -267,6 +283,30 @@ type ResourceMetricSource struct {
|
|||||||
TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"`
|
TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricSource indicates how to scale on a resource metric known to
|
||||||
|
// Kubernetes, as specified in the requests and limits, describing a single container in
|
||||||
|
// each of the pods of the current scale target(e.g. CPU or memory). The values will be
|
||||||
|
// averaged together before being compared to the target. Such metrics are built into
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source. Only one "target" type
|
||||||
|
// should be set.
|
||||||
|
type ContainerResourceMetricSource struct {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"`
|
||||||
|
// targetAverageUtilization is the target value of the average of the
|
||||||
|
// resource metric across all relevant pods, represented as a percentage of
|
||||||
|
// the requested value of the resource for the pods.
|
||||||
|
// +optional
|
||||||
|
TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty" protobuf:"varint,2,opt,name=targetAverageUtilization"`
|
||||||
|
// targetAverageValue is the target value of the average of the
|
||||||
|
// resource metric across all relevant pods, as a raw value (instead of as
|
||||||
|
// a percentage of the request), similar to the "pods" metric source type.
|
||||||
|
// +optional
|
||||||
|
TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"`
|
||||||
|
// container is the name of the container in the pods of the scaling target.
|
||||||
|
Container string `json:"container" protobuf:"bytes,5,opt,name=container"`
|
||||||
|
}
|
||||||
|
|
||||||
// ExternalMetricSource indicates how to scale on a metric not associated with
|
// ExternalMetricSource indicates how to scale on a metric not associated with
|
||||||
// any Kubernetes object (for example length of queue in cloud
|
// any Kubernetes object (for example length of queue in cloud
|
||||||
// messaging service, or QPS from loadbalancer running outside of cluster).
|
// messaging service, or QPS from loadbalancer running outside of cluster).
|
||||||
@ -289,8 +329,10 @@ type ExternalMetricSource struct {
|
|||||||
|
|
||||||
// MetricStatus describes the last-read state of a single metric.
|
// MetricStatus describes the last-read state of a single metric.
|
||||||
type MetricStatus struct {
|
type MetricStatus struct {
|
||||||
// type is the type of metric source. It will be one of "Object",
|
// type is the type of metric source. It will be one of "ContainerResource",
|
||||||
// "Pods" or "Resource", each corresponds to a matching field in the object.
|
// "External", "Object", "Pods" or "Resource", each corresponds to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -309,6 +351,13 @@ type MetricStatus struct {
|
|||||||
// to normal per-pod metrics using the "pods" source.
|
// to normal per-pod metrics using the "pods" source.
|
||||||
// +optional
|
// +optional
|
||||||
Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// +optional
|
||||||
|
ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"`
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -414,6 +463,30 @@ type ResourceMetricStatus struct {
|
|||||||
CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"`
|
CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricStatus indicates the current value of a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source.
|
||||||
|
type ContainerResourceMetricStatus struct {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"`
|
||||||
|
// currentAverageUtilization is the current value of the average of the
|
||||||
|
// resource metric across all relevant pods, represented as a percentage of
|
||||||
|
// the requested value of the resource for the pods. It will only be
|
||||||
|
// present if `targetAverageValue` was set in the corresponding metric
|
||||||
|
// specification.
|
||||||
|
// +optional
|
||||||
|
CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty" protobuf:"bytes,2,opt,name=currentAverageUtilization"`
|
||||||
|
// currentAverageValue is the current value of the average of the
|
||||||
|
// resource metric across all relevant pods, as a raw value (instead of as
|
||||||
|
// a percentage of the request), similar to the "pods" metric source type.
|
||||||
|
// It will always be set, regardless of the corresponding metric specification.
|
||||||
|
CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"`
|
||||||
|
// container is the name of the container in the pods of the scaling taget
|
||||||
|
Container string `json:"container" protobuf:"bytes,4,opt,name=container"`
|
||||||
|
}
|
||||||
|
|
||||||
// ExternalMetricStatus indicates the current value of a global metric
|
// ExternalMetricStatus indicates the current value of a global metric
|
||||||
// not associated with any Kubernetes object.
|
// not associated with any Kubernetes object.
|
||||||
type ExternalMetricStatus struct {
|
type ExternalMetricStatus struct {
|
||||||
|
@ -27,6 +27,30 @@ package v1
|
|||||||
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
||||||
|
|
||||||
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
||||||
|
var map_ContainerResourceMetricSource = map[string]string{
|
||||||
|
"": "ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in the requests and limits, describing a single container in each of the pods of the current scale target(e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built into Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.",
|
||||||
|
"name": "name is the name of the resource in question.",
|
||||||
|
"targetAverageUtilization": "targetAverageUtilization is the target value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.",
|
||||||
|
"targetAverageValue": "targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type.",
|
||||||
|
"container": "container is the name of the container in the pods of the scaling target.",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ContainerResourceMetricSource) SwaggerDoc() map[string]string {
|
||||||
|
return map_ContainerResourceMetricSource
|
||||||
|
}
|
||||||
|
|
||||||
|
var map_ContainerResourceMetricStatus = map[string]string{
|
||||||
|
"": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
"name": "name is the name of the resource in question.",
|
||||||
|
"currentAverageUtilization": "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods. It will only be present if `targetAverageValue` was set in the corresponding metric specification.",
|
||||||
|
"currentAverageValue": "currentAverageValue is the current value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type. It will always be set, regardless of the corresponding metric specification.",
|
||||||
|
"container": "container is the name of the container in the pods of the scaling taget",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string {
|
||||||
|
return map_ContainerResourceMetricStatus
|
||||||
|
}
|
||||||
|
|
||||||
var map_CrossVersionObjectReference = map[string]string{
|
var map_CrossVersionObjectReference = map[string]string{
|
||||||
"": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
"": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
||||||
"kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"",
|
"kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"",
|
||||||
@ -122,12 +146,13 @@ func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var map_MetricSpec = map[string]string{
|
var map_MetricSpec = map[string]string{
|
||||||
"": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
"": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
||||||
"type": "type is the type of metric source. It should be one of \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object.",
|
"type": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
||||||
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
||||||
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
"containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.",
|
||||||
|
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MetricSpec) SwaggerDoc() map[string]string {
|
func (MetricSpec) SwaggerDoc() map[string]string {
|
||||||
@ -135,12 +160,13 @@ func (MetricSpec) SwaggerDoc() map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var map_MetricStatus = map[string]string{
|
var map_MetricStatus = map[string]string{
|
||||||
"": "MetricStatus describes the last-read state of a single metric.",
|
"": "MetricStatus describes the last-read state of a single metric.",
|
||||||
"type": "type is the type of metric source. It will be one of \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.",
|
"type": "type is the type of metric source. It will be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
||||||
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
||||||
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
"containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MetricStatus) SwaggerDoc() map[string]string {
|
func (MetricStatus) SwaggerDoc() map[string]string {
|
||||||
|
@ -25,6 +25,54 @@ import (
|
|||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ContainerResourceMetricSource) DeepCopyInto(out *ContainerResourceMetricSource) {
|
||||||
|
*out = *in
|
||||||
|
if in.TargetAverageUtilization != nil {
|
||||||
|
in, out := &in.TargetAverageUtilization, &out.TargetAverageUtilization
|
||||||
|
*out = new(int32)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.TargetAverageValue != nil {
|
||||||
|
in, out := &in.TargetAverageValue, &out.TargetAverageValue
|
||||||
|
x := (*in).DeepCopy()
|
||||||
|
*out = &x
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricSource.
|
||||||
|
func (in *ContainerResourceMetricSource) DeepCopy() *ContainerResourceMetricSource {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ContainerResourceMetricSource)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ContainerResourceMetricStatus) DeepCopyInto(out *ContainerResourceMetricStatus) {
|
||||||
|
*out = *in
|
||||||
|
if in.CurrentAverageUtilization != nil {
|
||||||
|
in, out := &in.CurrentAverageUtilization, &out.CurrentAverageUtilization
|
||||||
|
*out = new(int32)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
out.CurrentAverageValue = in.CurrentAverageValue.DeepCopy()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricStatus.
|
||||||
|
func (in *ContainerResourceMetricStatus) DeepCopy() *ContainerResourceMetricStatus {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ContainerResourceMetricStatus)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@ -252,6 +300,11 @@ func (in *MetricSpec) DeepCopyInto(out *MetricSpec) {
|
|||||||
*out = new(ResourceMetricSource)
|
*out = new(ResourceMetricSource)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(ContainerResourceMetricSource)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(ExternalMetricSource)
|
*out = new(ExternalMetricSource)
|
||||||
@ -288,6 +341,11 @@ func (in *MetricStatus) DeepCopyInto(out *MetricStatus) {
|
|||||||
*out = new(ResourceMetricStatus)
|
*out = new(ResourceMetricStatus)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(ContainerResourceMetricStatus)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(ExternalMetricStatus)
|
*out = new(ExternalMetricStatus)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,60 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
|
|||||||
// Package-wide variables from generator "generated".
|
// Package-wide variables from generator "generated".
|
||||||
option go_package = "v2beta1";
|
option go_package = "v2beta1";
|
||||||
|
|
||||||
|
// ContainerResourceMetricSource indicates how to scale on a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). The values will be averaged
|
||||||
|
// together before being compared to the target. Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source. Only one "target" type
|
||||||
|
// should be set.
|
||||||
|
message ContainerResourceMetricSource {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
optional string name = 1;
|
||||||
|
|
||||||
|
// targetAverageUtilization is the target value of the average of the
|
||||||
|
// resource metric across all relevant pods, represented as a percentage of
|
||||||
|
// the requested value of the resource for the pods.
|
||||||
|
// +optional
|
||||||
|
optional int32 targetAverageUtilization = 2;
|
||||||
|
|
||||||
|
// targetAverageValue is the target value of the average of the
|
||||||
|
// resource metric across all relevant pods, as a raw value (instead of as
|
||||||
|
// a percentage of the request), similar to the "pods" metric source type.
|
||||||
|
// +optional
|
||||||
|
optional k8s.io.apimachinery.pkg.api.resource.Quantity targetAverageValue = 3;
|
||||||
|
|
||||||
|
// container is the name of the container in the pods of the scaling target
|
||||||
|
optional string container = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricStatus indicates the current value of a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source.
|
||||||
|
message ContainerResourceMetricStatus {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
optional string name = 1;
|
||||||
|
|
||||||
|
// currentAverageUtilization is the current value of the average of the
|
||||||
|
// resource metric across all relevant pods, represented as a percentage of
|
||||||
|
// the requested value of the resource for the pods. It will only be
|
||||||
|
// present if `targetAverageValue` was set in the corresponding metric
|
||||||
|
// specification.
|
||||||
|
// +optional
|
||||||
|
optional int32 currentAverageUtilization = 2;
|
||||||
|
|
||||||
|
// currentAverageValue is the current value of the average of the
|
||||||
|
// resource metric across all relevant pods, as a raw value (instead of as
|
||||||
|
// a percentage of the request), similar to the "pods" metric source type.
|
||||||
|
// It will always be set, regardless of the corresponding metric specification.
|
||||||
|
optional k8s.io.apimachinery.pkg.api.resource.Quantity currentAverageValue = 3;
|
||||||
|
|
||||||
|
// container is the name of the container in the pods of the scaling target
|
||||||
|
optional string container = 4;
|
||||||
|
}
|
||||||
|
|
||||||
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
|
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
|
||||||
message CrossVersionObjectReference {
|
message CrossVersionObjectReference {
|
||||||
// Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
|
// Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
|
||||||
@ -200,8 +254,10 @@ message HorizontalPodAutoscalerStatus {
|
|||||||
// MetricSpec specifies how to scale based on a single metric
|
// MetricSpec specifies how to scale based on a single metric
|
||||||
// (only `type` and one other matching field should be set at once).
|
// (only `type` and one other matching field should be set at once).
|
||||||
message MetricSpec {
|
message MetricSpec {
|
||||||
// type is the type of metric source. It should be one of "Object",
|
// type is the type of metric source. It should be one of "ContainerResource",
|
||||||
// "Pods", "Resource" or "External", each mapping to a matching field in the object.
|
// "External", "Object", "Pods" or "Resource", each mapping to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
optional string type = 1;
|
optional string type = 1;
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -223,6 +279,15 @@ message MetricSpec {
|
|||||||
// +optional
|
// +optional
|
||||||
optional ResourceMetricSource resource = 4;
|
optional ResourceMetricSource resource = 4;
|
||||||
|
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in
|
||||||
|
// each pod of the current scale target (e.g. CPU or memory). Such metrics are
|
||||||
|
// built in to Kubernetes, and have special scaling options on top of those
|
||||||
|
// available to normal per-pod metrics using the "pods" source.
|
||||||
|
// This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.
|
||||||
|
// +optional
|
||||||
|
optional ContainerResourceMetricSource containerResource = 7;
|
||||||
|
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -234,8 +299,10 @@ message MetricSpec {
|
|||||||
|
|
||||||
// MetricStatus describes the last-read state of a single metric.
|
// MetricStatus describes the last-read state of a single metric.
|
||||||
message MetricStatus {
|
message MetricStatus {
|
||||||
// type is the type of metric source. It will be one of "Object",
|
// type is the type of metric source. It will be one of "ContainerResource",
|
||||||
// "Pods" or "Resource", each corresponds to a matching field in the object.
|
// "External", "Object", "Pods" or "Resource", each corresponds to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
optional string type = 1;
|
optional string type = 1;
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -257,6 +324,14 @@ message MetricStatus {
|
|||||||
// +optional
|
// +optional
|
||||||
optional ResourceMetricStatus resource = 4;
|
optional ResourceMetricStatus resource = 4;
|
||||||
|
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// +optional
|
||||||
|
optional ContainerResourceMetricStatus containerResource = 7;
|
||||||
|
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
|
@ -76,6 +76,12 @@ const (
|
|||||||
// Kubernetes, and have special scaling options on top of those available
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
// to normal per-pod metrics (the "pods" source).
|
// to normal per-pod metrics (the "pods" source).
|
||||||
ResourceMetricSourceType MetricSourceType = "Resource"
|
ResourceMetricSourceType MetricSourceType = "Resource"
|
||||||
|
// ContainerResourceMetricSourceType is a resource metric known to Kubernetes, as
|
||||||
|
// specified in requests and limits, describing a single container in each pod in the current
|
||||||
|
// scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics (the "pods" source).
|
||||||
|
ContainerResourceMetricSourceType MetricSourceType = "ContainerResource"
|
||||||
// ExternalMetricSourceType is a global metric that is not associated
|
// ExternalMetricSourceType is a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -87,8 +93,10 @@ const (
|
|||||||
// MetricSpec specifies how to scale based on a single metric
|
// MetricSpec specifies how to scale based on a single metric
|
||||||
// (only `type` and one other matching field should be set at once).
|
// (only `type` and one other matching field should be set at once).
|
||||||
type MetricSpec struct {
|
type MetricSpec struct {
|
||||||
// type is the type of metric source. It should be one of "Object",
|
// type is the type of metric source. It should be one of "ContainerResource",
|
||||||
// "Pods", "Resource" or "External", each mapping to a matching field in the object.
|
// "External", "Object", "Pods" or "Resource", each mapping to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -107,6 +115,14 @@ type MetricSpec struct {
|
|||||||
// to normal per-pod metrics using the "pods" source.
|
// to normal per-pod metrics using the "pods" source.
|
||||||
// +optional
|
// +optional
|
||||||
Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in
|
||||||
|
// each pod of the current scale target (e.g. CPU or memory). Such metrics are
|
||||||
|
// built in to Kubernetes, and have special scaling options on top of those
|
||||||
|
// available to normal per-pod metrics using the "pods" source.
|
||||||
|
// This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.
|
||||||
|
// +optional
|
||||||
|
ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"`
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -178,6 +194,30 @@ type ResourceMetricSource struct {
|
|||||||
TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"`
|
TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricSource indicates how to scale on a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). The values will be averaged
|
||||||
|
// together before being compared to the target. Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source. Only one "target" type
|
||||||
|
// should be set.
|
||||||
|
type ContainerResourceMetricSource struct {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"`
|
||||||
|
// targetAverageUtilization is the target value of the average of the
|
||||||
|
// resource metric across all relevant pods, represented as a percentage of
|
||||||
|
// the requested value of the resource for the pods.
|
||||||
|
// +optional
|
||||||
|
TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty" protobuf:"varint,2,opt,name=targetAverageUtilization"`
|
||||||
|
// targetAverageValue is the target value of the average of the
|
||||||
|
// resource metric across all relevant pods, as a raw value (instead of as
|
||||||
|
// a percentage of the request), similar to the "pods" metric source type.
|
||||||
|
// +optional
|
||||||
|
TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"`
|
||||||
|
// container is the name of the container in the pods of the scaling target
|
||||||
|
Container string `json:"container" protobuf:"bytes,4,opt,name=container"`
|
||||||
|
}
|
||||||
|
|
||||||
// ExternalMetricSource indicates how to scale on a metric not associated with
|
// ExternalMetricSource indicates how to scale on a metric not associated with
|
||||||
// any Kubernetes object (for example length of queue in cloud
|
// any Kubernetes object (for example length of queue in cloud
|
||||||
// messaging service, or QPS from loadbalancer running outside of cluster).
|
// messaging service, or QPS from loadbalancer running outside of cluster).
|
||||||
@ -265,8 +305,10 @@ type HorizontalPodAutoscalerCondition struct {
|
|||||||
|
|
||||||
// MetricStatus describes the last-read state of a single metric.
|
// MetricStatus describes the last-read state of a single metric.
|
||||||
type MetricStatus struct {
|
type MetricStatus struct {
|
||||||
// type is the type of metric source. It will be one of "Object",
|
// type is the type of metric source. It will be one of "ContainerResource",
|
||||||
// "Pods" or "Resource", each corresponds to a matching field in the object.
|
// "External", "Object", "Pods" or "Resource", each corresponds to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -285,6 +327,13 @@ type MetricStatus struct {
|
|||||||
// to normal per-pod metrics using the "pods" source.
|
// to normal per-pod metrics using the "pods" source.
|
||||||
// +optional
|
// +optional
|
||||||
Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// +optional
|
||||||
|
ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"`
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -354,6 +403,30 @@ type ResourceMetricStatus struct {
|
|||||||
CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"`
|
CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricStatus indicates the current value of a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source.
|
||||||
|
type ContainerResourceMetricStatus struct {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"`
|
||||||
|
// currentAverageUtilization is the current value of the average of the
|
||||||
|
// resource metric across all relevant pods, represented as a percentage of
|
||||||
|
// the requested value of the resource for the pods. It will only be
|
||||||
|
// present if `targetAverageValue` was set in the corresponding metric
|
||||||
|
// specification.
|
||||||
|
// +optional
|
||||||
|
CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty" protobuf:"bytes,2,opt,name=currentAverageUtilization"`
|
||||||
|
// currentAverageValue is the current value of the average of the
|
||||||
|
// resource metric across all relevant pods, as a raw value (instead of as
|
||||||
|
// a percentage of the request), similar to the "pods" metric source type.
|
||||||
|
// It will always be set, regardless of the corresponding metric specification.
|
||||||
|
CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"`
|
||||||
|
// container is the name of the container in the pods of the scaling target
|
||||||
|
Container string `json:"container" protobuf:"bytes,4,opt,name=container"`
|
||||||
|
}
|
||||||
|
|
||||||
// ExternalMetricStatus indicates the current value of a global metric
|
// ExternalMetricStatus indicates the current value of a global metric
|
||||||
// not associated with any Kubernetes object.
|
// not associated with any Kubernetes object.
|
||||||
type ExternalMetricStatus struct {
|
type ExternalMetricStatus struct {
|
||||||
|
@ -27,6 +27,30 @@ package v2beta1
|
|||||||
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
||||||
|
|
||||||
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
||||||
|
var map_ContainerResourceMetricSource = map[string]string{
|
||||||
|
"": "ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.",
|
||||||
|
"name": "name is the name of the resource in question.",
|
||||||
|
"targetAverageUtilization": "targetAverageUtilization is the target value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.",
|
||||||
|
"targetAverageValue": "targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type.",
|
||||||
|
"container": "container is the name of the container in the pods of the scaling target",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ContainerResourceMetricSource) SwaggerDoc() map[string]string {
|
||||||
|
return map_ContainerResourceMetricSource
|
||||||
|
}
|
||||||
|
|
||||||
|
var map_ContainerResourceMetricStatus = map[string]string{
|
||||||
|
"": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
"name": "name is the name of the resource in question.",
|
||||||
|
"currentAverageUtilization": "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods. It will only be present if `targetAverageValue` was set in the corresponding metric specification.",
|
||||||
|
"currentAverageValue": "currentAverageValue is the current value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type. It will always be set, regardless of the corresponding metric specification.",
|
||||||
|
"container": "container is the name of the container in the pods of the scaling target",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string {
|
||||||
|
return map_ContainerResourceMetricStatus
|
||||||
|
}
|
||||||
|
|
||||||
var map_CrossVersionObjectReference = map[string]string{
|
var map_CrossVersionObjectReference = map[string]string{
|
||||||
"": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
"": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
||||||
"kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"",
|
"kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"",
|
||||||
@ -123,12 +147,13 @@ func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var map_MetricSpec = map[string]string{
|
var map_MetricSpec = map[string]string{
|
||||||
"": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
"": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
||||||
"type": "type is the type of metric source. It should be one of \"Object\", \"Pods\", \"Resource\" or \"External\", each mapping to a matching field in the object.",
|
"type": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
||||||
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
||||||
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
"containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.",
|
||||||
|
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MetricSpec) SwaggerDoc() map[string]string {
|
func (MetricSpec) SwaggerDoc() map[string]string {
|
||||||
@ -136,12 +161,13 @@ func (MetricSpec) SwaggerDoc() map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var map_MetricStatus = map[string]string{
|
var map_MetricStatus = map[string]string{
|
||||||
"": "MetricStatus describes the last-read state of a single metric.",
|
"": "MetricStatus describes the last-read state of a single metric.",
|
||||||
"type": "type is the type of metric source. It will be one of \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.",
|
"type": "type is the type of metric source. It will be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
||||||
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
||||||
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
"containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MetricStatus) SwaggerDoc() map[string]string {
|
func (MetricStatus) SwaggerDoc() map[string]string {
|
||||||
|
@ -25,6 +25,54 @@ import (
|
|||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ContainerResourceMetricSource) DeepCopyInto(out *ContainerResourceMetricSource) {
|
||||||
|
*out = *in
|
||||||
|
if in.TargetAverageUtilization != nil {
|
||||||
|
in, out := &in.TargetAverageUtilization, &out.TargetAverageUtilization
|
||||||
|
*out = new(int32)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.TargetAverageValue != nil {
|
||||||
|
in, out := &in.TargetAverageValue, &out.TargetAverageValue
|
||||||
|
x := (*in).DeepCopy()
|
||||||
|
*out = &x
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricSource.
|
||||||
|
func (in *ContainerResourceMetricSource) DeepCopy() *ContainerResourceMetricSource {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ContainerResourceMetricSource)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ContainerResourceMetricStatus) DeepCopyInto(out *ContainerResourceMetricStatus) {
|
||||||
|
*out = *in
|
||||||
|
if in.CurrentAverageUtilization != nil {
|
||||||
|
in, out := &in.CurrentAverageUtilization, &out.CurrentAverageUtilization
|
||||||
|
*out = new(int32)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
out.CurrentAverageValue = in.CurrentAverageValue.DeepCopy()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricStatus.
|
||||||
|
func (in *ContainerResourceMetricStatus) DeepCopy() *ContainerResourceMetricStatus {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ContainerResourceMetricStatus)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@ -263,6 +311,11 @@ func (in *MetricSpec) DeepCopyInto(out *MetricSpec) {
|
|||||||
*out = new(ResourceMetricSource)
|
*out = new(ResourceMetricSource)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(ContainerResourceMetricSource)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(ExternalMetricSource)
|
*out = new(ExternalMetricSource)
|
||||||
@ -299,6 +352,11 @@ func (in *MetricStatus) DeepCopyInto(out *MetricStatus) {
|
|||||||
*out = new(ResourceMetricStatus)
|
*out = new(ResourceMetricStatus)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(ContainerResourceMetricStatus)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(ExternalMetricStatus)
|
*out = new(ExternalMetricStatus)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,40 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
|
|||||||
// Package-wide variables from generator "generated".
|
// Package-wide variables from generator "generated".
|
||||||
option go_package = "v2beta2";
|
option go_package = "v2beta2";
|
||||||
|
|
||||||
|
// ContainerResourceMetricSource indicates how to scale on a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). The values will be averaged
|
||||||
|
// together before being compared to the target. Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source. Only one "target" type
|
||||||
|
// should be set.
|
||||||
|
message ContainerResourceMetricSource {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
optional string name = 1;
|
||||||
|
|
||||||
|
// target specifies the target value for the given metric
|
||||||
|
optional MetricTarget target = 2;
|
||||||
|
|
||||||
|
// container is the name of the container in the pods of the scaling target
|
||||||
|
optional string container = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricStatus indicates the current value of a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source.
|
||||||
|
message ContainerResourceMetricStatus {
|
||||||
|
// Name is the name of the resource in question.
|
||||||
|
optional string name = 1;
|
||||||
|
|
||||||
|
// current contains the current value for the given metric
|
||||||
|
optional MetricValueStatus current = 2;
|
||||||
|
|
||||||
|
// Container is the name of the container in the pods of the scaling target
|
||||||
|
optional string container = 3;
|
||||||
|
}
|
||||||
|
|
||||||
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
|
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
|
||||||
message CrossVersionObjectReference {
|
message CrossVersionObjectReference {
|
||||||
// Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
|
// Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"
|
||||||
@ -256,8 +290,10 @@ message MetricIdentifier {
|
|||||||
// MetricSpec specifies how to scale based on a single metric
|
// MetricSpec specifies how to scale based on a single metric
|
||||||
// (only `type` and one other matching field should be set at once).
|
// (only `type` and one other matching field should be set at once).
|
||||||
message MetricSpec {
|
message MetricSpec {
|
||||||
// type is the type of metric source. It should be one of "Object",
|
// type is the type of metric source. It should be one of "ContainerResource", "External",
|
||||||
// "Pods", "Resource" or "External", each mapping to a matching field in the object.
|
// "Object", "Pods" or "Resource", each mapping to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
optional string type = 1;
|
optional string type = 1;
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -279,6 +315,15 @@ message MetricSpec {
|
|||||||
// +optional
|
// +optional
|
||||||
optional ResourceMetricSource resource = 4;
|
optional ResourceMetricSource resource = 4;
|
||||||
|
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in
|
||||||
|
// each pod of the current scale target (e.g. CPU or memory). Such metrics are
|
||||||
|
// built in to Kubernetes, and have special scaling options on top of those
|
||||||
|
// available to normal per-pod metrics using the "pods" source.
|
||||||
|
// This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.
|
||||||
|
// +optional
|
||||||
|
optional ContainerResourceMetricSource containerResource = 7;
|
||||||
|
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -290,8 +335,10 @@ message MetricSpec {
|
|||||||
|
|
||||||
// MetricStatus describes the last-read state of a single metric.
|
// MetricStatus describes the last-read state of a single metric.
|
||||||
message MetricStatus {
|
message MetricStatus {
|
||||||
// type is the type of metric source. It will be one of "Object",
|
// type is the type of metric source. It will be one of "ContainerResource", "External",
|
||||||
// "Pods" or "Resource", each corresponds to a matching field in the object.
|
// "Object", "Pods" or "Resource", each corresponds to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
optional string type = 1;
|
optional string type = 1;
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -313,6 +360,14 @@ message MetricStatus {
|
|||||||
// +optional
|
// +optional
|
||||||
optional ResourceMetricStatus resource = 4;
|
optional ResourceMetricStatus resource = 4;
|
||||||
|
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// +optional
|
||||||
|
optional ContainerResourceMetricStatus containerResource = 7;
|
||||||
|
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
|
@ -96,8 +96,10 @@ type CrossVersionObjectReference struct {
|
|||||||
// MetricSpec specifies how to scale based on a single metric
|
// MetricSpec specifies how to scale based on a single metric
|
||||||
// (only `type` and one other matching field should be set at once).
|
// (only `type` and one other matching field should be set at once).
|
||||||
type MetricSpec struct {
|
type MetricSpec struct {
|
||||||
// type is the type of metric source. It should be one of "Object",
|
// type is the type of metric source. It should be one of "ContainerResource", "External",
|
||||||
// "Pods", "Resource" or "External", each mapping to a matching field in the object.
|
// "Object", "Pods" or "Resource", each mapping to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -116,6 +118,14 @@ type MetricSpec struct {
|
|||||||
// to normal per-pod metrics using the "pods" source.
|
// to normal per-pod metrics using the "pods" source.
|
||||||
// +optional
|
// +optional
|
||||||
Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in
|
||||||
|
// each pod of the current scale target (e.g. CPU or memory). Such metrics are
|
||||||
|
// built in to Kubernetes, and have special scaling options on top of those
|
||||||
|
// available to normal per-pod metrics using the "pods" source.
|
||||||
|
// This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.
|
||||||
|
// +optional
|
||||||
|
ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"`
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -220,6 +230,12 @@ const (
|
|||||||
// Kubernetes, and have special scaling options on top of those available
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
// to normal per-pod metrics (the "pods" source).
|
// to normal per-pod metrics (the "pods" source).
|
||||||
ResourceMetricSourceType MetricSourceType = "Resource"
|
ResourceMetricSourceType MetricSourceType = "Resource"
|
||||||
|
// ContainerResourceMetricSourceType is a resource metric known to Kubernetes, as
|
||||||
|
// specified in requests and limits, describing a single container in each pod in the current
|
||||||
|
// scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics (the "pods" source).
|
||||||
|
ContainerResourceMetricSourceType MetricSourceType = "ContainerResource"
|
||||||
// ExternalMetricSourceType is a global metric that is not associated
|
// ExternalMetricSourceType is a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -263,6 +279,22 @@ type ResourceMetricSource struct {
|
|||||||
Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"`
|
Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricSource indicates how to scale on a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). The values will be averaged
|
||||||
|
// together before being compared to the target. Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source. Only one "target" type
|
||||||
|
// should be set.
|
||||||
|
type ContainerResourceMetricSource struct {
|
||||||
|
// name is the name of the resource in question.
|
||||||
|
Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"`
|
||||||
|
// target specifies the target value for the given metric
|
||||||
|
Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"`
|
||||||
|
// container is the name of the container in the pods of the scaling target
|
||||||
|
Container string `json:"container" protobuf:"bytes,3,opt,name=container"`
|
||||||
|
}
|
||||||
|
|
||||||
// ExternalMetricSource indicates how to scale on a metric not associated with
|
// ExternalMetricSource indicates how to scale on a metric not associated with
|
||||||
// any Kubernetes object (for example length of queue in cloud
|
// any Kubernetes object (for example length of queue in cloud
|
||||||
// messaging service, or QPS from loadbalancer running outside of cluster).
|
// messaging service, or QPS from loadbalancer running outside of cluster).
|
||||||
@ -382,8 +414,10 @@ type HorizontalPodAutoscalerCondition struct {
|
|||||||
|
|
||||||
// MetricStatus describes the last-read state of a single metric.
|
// MetricStatus describes the last-read state of a single metric.
|
||||||
type MetricStatus struct {
|
type MetricStatus struct {
|
||||||
// type is the type of metric source. It will be one of "Object",
|
// type is the type of metric source. It will be one of "ContainerResource", "External",
|
||||||
// "Pods" or "Resource", each corresponds to a matching field in the object.
|
// "Object", "Pods" or "Resource", each corresponds to a matching field in the object.
|
||||||
|
// Note: "ContainerResource" type is available on when the feature-gate
|
||||||
|
// HPAContainerMetrics is enabled
|
||||||
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"`
|
||||||
|
|
||||||
// object refers to a metric describing a single kubernetes object
|
// object refers to a metric describing a single kubernetes object
|
||||||
@ -402,6 +436,13 @@ type MetricStatus struct {
|
|||||||
// to normal per-pod metrics using the "pods" source.
|
// to normal per-pod metrics using the "pods" source.
|
||||||
// +optional
|
// +optional
|
||||||
Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
|
||||||
|
// container resource refers to a resource metric (such as those specified in
|
||||||
|
// requests and limits) known to Kubernetes describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available
|
||||||
|
// to normal per-pod metrics using the "pods" source.
|
||||||
|
// +optional
|
||||||
|
ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"`
|
||||||
// external refers to a global metric that is not associated
|
// external refers to a global metric that is not associated
|
||||||
// with any Kubernetes object. It allows autoscaling based on information
|
// with any Kubernetes object. It allows autoscaling based on information
|
||||||
// coming from components running outside of cluster
|
// coming from components running outside of cluster
|
||||||
@ -443,6 +484,20 @@ type ResourceMetricStatus struct {
|
|||||||
Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"`
|
Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerResourceMetricStatus indicates the current value of a resource metric known to
|
||||||
|
// Kubernetes, as specified in requests and limits, describing a single container in each pod in the
|
||||||
|
// current scale target (e.g. CPU or memory). Such metrics are built in to
|
||||||
|
// Kubernetes, and have special scaling options on top of those available to
|
||||||
|
// normal per-pod metrics using the "pods" source.
|
||||||
|
type ContainerResourceMetricStatus struct {
|
||||||
|
// Name is the name of the resource in question.
|
||||||
|
Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"`
|
||||||
|
// current contains the current value for the given metric
|
||||||
|
Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"`
|
||||||
|
// Container is the name of the container in the pods of the scaling target
|
||||||
|
Container string `json:"container" protobuf:"bytes,3,opt,name=container"`
|
||||||
|
}
|
||||||
|
|
||||||
// ExternalMetricStatus indicates the current value of a global metric
|
// ExternalMetricStatus indicates the current value of a global metric
|
||||||
// not associated with any Kubernetes object.
|
// not associated with any Kubernetes object.
|
||||||
type ExternalMetricStatus struct {
|
type ExternalMetricStatus struct {
|
||||||
|
@ -27,6 +27,28 @@ package v2beta2
|
|||||||
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
||||||
|
|
||||||
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
||||||
|
var map_ContainerResourceMetricSource = map[string]string{
|
||||||
|
"": "ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.",
|
||||||
|
"name": "name is the name of the resource in question.",
|
||||||
|
"target": "target specifies the target value for the given metric",
|
||||||
|
"container": "container is the name of the container in the pods of the scaling target",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ContainerResourceMetricSource) SwaggerDoc() map[string]string {
|
||||||
|
return map_ContainerResourceMetricSource
|
||||||
|
}
|
||||||
|
|
||||||
|
var map_ContainerResourceMetricStatus = map[string]string{
|
||||||
|
"": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
"name": "Name is the name of the resource in question.",
|
||||||
|
"current": "current contains the current value for the given metric",
|
||||||
|
"container": "Container is the name of the container in the pods of the scaling target",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string {
|
||||||
|
return map_ContainerResourceMetricStatus
|
||||||
|
}
|
||||||
|
|
||||||
var map_CrossVersionObjectReference = map[string]string{
|
var map_CrossVersionObjectReference = map[string]string{
|
||||||
"": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
"": "CrossVersionObjectReference contains enough information to let you identify the referred resource.",
|
||||||
"kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"",
|
"kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"",
|
||||||
@ -162,12 +184,13 @@ func (MetricIdentifier) SwaggerDoc() map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var map_MetricSpec = map[string]string{
|
var map_MetricSpec = map[string]string{
|
||||||
"": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
"": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).",
|
||||||
"type": "type is the type of metric source. It should be one of \"Object\", \"Pods\", \"Resource\" or \"External\", each mapping to a matching field in the object.",
|
"type": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
||||||
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
||||||
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
"containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.",
|
||||||
|
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MetricSpec) SwaggerDoc() map[string]string {
|
func (MetricSpec) SwaggerDoc() map[string]string {
|
||||||
@ -175,12 +198,13 @@ func (MetricSpec) SwaggerDoc() map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var map_MetricStatus = map[string]string{
|
var map_MetricStatus = map[string]string{
|
||||||
"": "MetricStatus describes the last-read state of a single metric.",
|
"": "MetricStatus describes the last-read state of a single metric.",
|
||||||
"type": "type is the type of metric source. It will be one of \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.",
|
"type": "type is the type of metric source. It will be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
"object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).",
|
||||||
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
"pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.",
|
||||||
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
"resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
"containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
"external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MetricStatus) SwaggerDoc() map[string]string {
|
func (MetricStatus) SwaggerDoc() map[string]string {
|
||||||
|
@ -25,6 +25,40 @@ import (
|
|||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ContainerResourceMetricSource) DeepCopyInto(out *ContainerResourceMetricSource) {
|
||||||
|
*out = *in
|
||||||
|
in.Target.DeepCopyInto(&out.Target)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricSource.
|
||||||
|
func (in *ContainerResourceMetricSource) DeepCopy() *ContainerResourceMetricSource {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ContainerResourceMetricSource)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ContainerResourceMetricStatus) DeepCopyInto(out *ContainerResourceMetricStatus) {
|
||||||
|
*out = *in
|
||||||
|
in.Current.DeepCopyInto(&out.Current)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricStatus.
|
||||||
|
func (in *ContainerResourceMetricStatus) DeepCopy() *ContainerResourceMetricStatus {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ContainerResourceMetricStatus)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@ -340,6 +374,11 @@ func (in *MetricSpec) DeepCopyInto(out *MetricSpec) {
|
|||||||
*out = new(ResourceMetricSource)
|
*out = new(ResourceMetricSource)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(ContainerResourceMetricSource)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(ExternalMetricSource)
|
*out = new(ExternalMetricSource)
|
||||||
@ -376,6 +415,11 @@ func (in *MetricStatus) DeepCopyInto(out *MetricStatus) {
|
|||||||
*out = new(ResourceMetricStatus)
|
*out = new(ResourceMetricStatus)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.ContainerResource != nil {
|
||||||
|
in, out := &in.ContainerResource, &out.ContainerResource
|
||||||
|
*out = new(ContainerResourceMetricStatus)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.External != nil {
|
if in.External != nil {
|
||||||
in, out := &in.External, &out.External
|
in, out := &in.External, &out.External
|
||||||
*out = new(ExternalMetricStatus)
|
*out = new(ExternalMetricStatus)
|
||||||
|
@ -98,98 +98,122 @@
|
|||||||
"targetAverageUtilization": 1253093074,
|
"targetAverageUtilization": 1253093074,
|
||||||
"targetAverageValue": "8"
|
"targetAverageValue": "8"
|
||||||
},
|
},
|
||||||
|
"containerResource": {
|
||||||
|
"name": "w垁鷌辪虽U珝Żwʮ馜üNșƶ4ĩ",
|
||||||
|
"targetAverageUtilization": 1463207240,
|
||||||
|
"targetAverageValue": "84",
|
||||||
|
"container": "39"
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
"metricName": "39",
|
"metricName": "40",
|
||||||
"metricSelector": {
|
"metricSelector": {
|
||||||
"matchLabels": {
|
"matchLabels": {
|
||||||
"4kh6oqu-or---40--87-1wpl6-2-310e5hz/B._z": "G6t-2.-_-8w6"
|
"bigm-h8-3q768km-0--03-t-0-035--5b95w------4-n4f-h/u-5.-Z3P__D__6t-2.-_-8wE._._3.-.83_iq_-1": "1-_Y33--.8U.-.5--_zm-.-_RJt2pX_2_28.-.7_8B.HF-U-_ik_--DSX0"
|
||||||
},
|
},
|
||||||
"matchExpressions": [
|
"matchExpressions": [
|
||||||
{
|
{
|
||||||
"key": "1295at-o7qff7-x--r7v66bm71u-n4f9wk-3--652x01--p--n4-4-t--2gk-0/d.83_iq_-y.-25C.A-j..9dfn3Y8d_0_.---M_4FpF_W-1._-vL_i.-_-a--GI",
|
"key": "680---z-6-t2z-w-fg98-r--v53nyx5u-o-k-md--381d-7.3di292f--90-17-hg1-o-p665--4-j8---t6-r7r/Y-H-Mqpt._.-_..05c.---qy-_5_S.d5a37",
|
||||||
"operator": "DoesNotExist"
|
"operator": "NotIn",
|
||||||
|
"values": [
|
||||||
|
"dY_um-_8r--684._-_18_...E.-2o_-.5"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"targetValue": "570",
|
"targetValue": "865",
|
||||||
"targetAverageValue": "829"
|
"targetAverageValue": "379"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"observedGeneration": -7224326297454280417,
|
"observedGeneration": 61436896663269868,
|
||||||
"currentReplicas": 596942561,
|
"currentReplicas": -1462219068,
|
||||||
"desiredReplicas": -1880980172,
|
"desiredReplicas": -370386363,
|
||||||
"currentMetrics": [
|
"currentMetrics": [
|
||||||
{
|
{
|
||||||
"type": " ïì«丯Ƙ枛牐ɺ皚|懥",
|
"type": "",
|
||||||
"object": {
|
"object": {
|
||||||
"target": {
|
"target": {
|
||||||
"kind": "46",
|
"kind": "47",
|
||||||
"name": "47",
|
"name": "48",
|
||||||
"apiVersion": "48"
|
"apiVersion": "49"
|
||||||
},
|
},
|
||||||
"metricName": "49",
|
"metricName": "50",
|
||||||
"currentValue": "55",
|
"currentValue": "856",
|
||||||
"selector": {
|
"selector": {
|
||||||
"matchLabels": {
|
"matchLabels": {
|
||||||
"8._Wxpe..J7rs6.0_OHz_.B-.-_w_--.8_r_N-.3n-xu": "o_-Nm-_X8"
|
"vL7": "L_0N_N.O30-_u._-2hT.-z-._7-5lL..-_--.VEa-_gn.8-c.C3_F._oX-FT"
|
||||||
},
|
},
|
||||||
"matchExpressions": [
|
"matchExpressions": [
|
||||||
{
|
{
|
||||||
"key": "665--4-j8---t6-r7--9.9dy/XvSA..1",
|
"key": "4_.-N_g-.._5",
|
||||||
"operator": "Exists"
|
"operator": "In",
|
||||||
|
"values": [
|
||||||
|
"2qz.W..4....-h._.GgT7_7B_D-..-.k4u-zA_--_.-.6GA26C-s.Nj-d-4_t"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"averageValue": "14"
|
"averageValue": "817"
|
||||||
},
|
},
|
||||||
"pods": {
|
"pods": {
|
||||||
"metricName": "56",
|
"metricName": "57",
|
||||||
"currentAverageValue": "878",
|
"currentAverageValue": "400",
|
||||||
"selector": {
|
"selector": {
|
||||||
"matchLabels": {
|
"matchLabels": {
|
||||||
"6fv--m-8--72-bca4m56au3f-j/0-_1-F.h-__k_K5._..O_.J_-G_--V-42E_--o90G_A4..-L..-__0N_N.O3i": "r_gn.8-c.C3_F._oX-F9_.v"
|
"mj_9.M.134-5-.q6H_.--_---.M.U_-m.-P.yP9S--858LI__.8U": "KrO-S-P_-...0c.-.p_3_J_SA995IKCR.s--f.-f.-zv._._.5-HT"
|
||||||
},
|
},
|
||||||
"matchExpressions": [
|
"matchExpressions": [
|
||||||
{
|
{
|
||||||
"key": "g-..__._____K_g1cXfr.4_.B",
|
"key": "26-k8-c2---2etfh41ca-z-5g2wco280.ka-6-31g--z-o-3bz6-8-0-1-z--271s-p9-8--m-cbck561-7n/VC..7o_x3..-.8J",
|
||||||
"operator": "DoesNotExist"
|
"operator": "NotIn",
|
||||||
|
"values": [
|
||||||
|
"8._Q.6.I--2_9.v.--_.--4QQ.-s.H.Hf"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"name": "šeSvEȤƏ埮pɵ{WOŭW灬pȭ",
|
"name": "ƻ遲njlȘ鹾KƂʼnç",
|
||||||
"currentAverageUtilization": -1607821167,
|
"currentAverageUtilization": 769521729,
|
||||||
"currentAverageValue": "832"
|
"currentAverageValue": "727"
|
||||||
|
},
|
||||||
|
"containerResource": {
|
||||||
|
"name": "!@@)Zq=",
|
||||||
|
"currentAverageUtilization": -861915578,
|
||||||
|
"currentAverageValue": "111",
|
||||||
|
"container": "64"
|
||||||
},
|
},
|
||||||
"external": {
|
"external": {
|
||||||
"metricName": "63",
|
"metricName": "65",
|
||||||
"metricSelector": {
|
"metricSelector": {
|
||||||
"matchLabels": {
|
"matchLabels": {
|
||||||
"4_4--.-_Z4.LA3HVG93_._.I3.__-.0-z_z0sn_.hx_-a__0-8-.M-.-.-8vJ": "zET_..3dCv3j._.-_pP__up.2L_s-o779._-k-5___-Qq4"
|
"2y3-4-3/AO": "r..6W.V0"
|
||||||
},
|
},
|
||||||
"matchExpressions": [
|
"matchExpressions": [
|
||||||
{
|
{
|
||||||
"key": "FC-rtSY.g._2F7.-_e..OP",
|
"key": "v55039780bdw0-1-47rrw8-7/U_--56-.7D.3_KPg___Kp",
|
||||||
"operator": "Exists"
|
"operator": "In",
|
||||||
|
"values": [
|
||||||
|
"N7_-Zp_._w"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"currentValue": "229",
|
"currentValue": "200",
|
||||||
"currentAverageValue": "606"
|
"currentAverageValue": "288"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"conditions": [
|
"conditions": [
|
||||||
{
|
{
|
||||||
"type": "鯶縆",
|
"type": "",
|
||||||
"status": "aTGÒ鵌Ē3",
|
"status": "",
|
||||||
"lastTransitionTime": "2416-12-01T11:47:49Z",
|
"lastTransitionTime": "1995-10-31T09:59:43Z",
|
||||||
"reason": "70",
|
"reason": "72",
|
||||||
"message": "71"
|
"message": "73"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -32,16 +32,23 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
maxReplicas: -1971381490
|
maxReplicas: -1971381490
|
||||||
metrics:
|
metrics:
|
||||||
- external:
|
- containerResource:
|
||||||
metricName: "39"
|
container: "39"
|
||||||
|
name: w垁鷌辪虽U珝Żwʮ馜üNșƶ4ĩ
|
||||||
|
targetAverageUtilization: 1463207240
|
||||||
|
targetAverageValue: "84"
|
||||||
|
external:
|
||||||
|
metricName: "40"
|
||||||
metricSelector:
|
metricSelector:
|
||||||
matchExpressions:
|
matchExpressions:
|
||||||
- key: 1295at-o7qff7-x--r7v66bm71u-n4f9wk-3--652x01--p--n4-4-t--2gk-0/d.83_iq_-y.-25C.A-j..9dfn3Y8d_0_.---M_4FpF_W-1._-vL_i.-_-a--GI
|
- key: 680---z-6-t2z-w-fg98-r--v53nyx5u-o-k-md--381d-7.3di292f--90-17-hg1-o-p665--4-j8---t6-r7r/Y-H-Mqpt._.-_..05c.---qy-_5_S.d5a37
|
||||||
operator: DoesNotExist
|
operator: NotIn
|
||||||
|
values:
|
||||||
|
- dY_um-_8r--684._-_18_...E.-2o_-.5
|
||||||
matchLabels:
|
matchLabels:
|
||||||
4kh6oqu-or---40--87-1wpl6-2-310e5hz/B._z: G6t-2.-_-8w6
|
bigm-h8-3q768km-0--03-t-0-035--5b95w------4-n4f-h/u-5.-Z3P__D__6t-2.-_-8wE._._3.-.83_iq_-1: 1-_Y33--.8U.-.5--_zm-.-_RJt2pX_2_28.-.7_8B.HF-U-_ik_--DSX0
|
||||||
targetAverageValue: "829"
|
targetAverageValue: "379"
|
||||||
targetValue: "570"
|
targetValue: "865"
|
||||||
object:
|
object:
|
||||||
averageValue: "954"
|
averageValue: "954"
|
||||||
metricName: "25"
|
metricName: "25"
|
||||||
@ -82,50 +89,61 @@ spec:
|
|||||||
name: "20"
|
name: "20"
|
||||||
status:
|
status:
|
||||||
conditions:
|
conditions:
|
||||||
- lastTransitionTime: "2416-12-01T11:47:49Z"
|
- lastTransitionTime: "1995-10-31T09:59:43Z"
|
||||||
message: "71"
|
message: "73"
|
||||||
reason: "70"
|
reason: "72"
|
||||||
status: aTGÒ鵌Ē3
|
status: ""
|
||||||
type: 鯶縆
|
type: ""
|
||||||
currentMetrics:
|
currentMetrics:
|
||||||
- external:
|
- containerResource:
|
||||||
currentAverageValue: "606"
|
container: "64"
|
||||||
currentValue: "229"
|
currentAverageUtilization: -861915578
|
||||||
metricName: "63"
|
currentAverageValue: "111"
|
||||||
|
name: '!@@)Zq='
|
||||||
|
external:
|
||||||
|
currentAverageValue: "288"
|
||||||
|
currentValue: "200"
|
||||||
|
metricName: "65"
|
||||||
metricSelector:
|
metricSelector:
|
||||||
matchExpressions:
|
matchExpressions:
|
||||||
- key: FC-rtSY.g._2F7.-_e..OP
|
- key: v55039780bdw0-1-47rrw8-7/U_--56-.7D.3_KPg___Kp
|
||||||
operator: Exists
|
operator: In
|
||||||
|
values:
|
||||||
|
- N7_-Zp_._w
|
||||||
matchLabels:
|
matchLabels:
|
||||||
4_4--.-_Z4.LA3HVG93_._.I3.__-.0-z_z0sn_.hx_-a__0-8-.M-.-.-8vJ: zET_..3dCv3j._.-_pP__up.2L_s-o779._-k-5___-Qq4
|
2y3-4-3/AO: r..6W.V0
|
||||||
object:
|
object:
|
||||||
averageValue: "14"
|
averageValue: "817"
|
||||||
currentValue: "55"
|
currentValue: "856"
|
||||||
metricName: "49"
|
metricName: "50"
|
||||||
selector:
|
selector:
|
||||||
matchExpressions:
|
matchExpressions:
|
||||||
- key: 665--4-j8---t6-r7--9.9dy/XvSA..1
|
- key: 4_.-N_g-.._5
|
||||||
operator: Exists
|
operator: In
|
||||||
|
values:
|
||||||
|
- 2qz.W..4....-h._.GgT7_7B_D-..-.k4u-zA_--_.-.6GA26C-s.Nj-d-4_t
|
||||||
matchLabels:
|
matchLabels:
|
||||||
8._Wxpe..J7rs6.0_OHz_.B-.-_w_--.8_r_N-.3n-xu: o_-Nm-_X8
|
vL7: L_0N_N.O30-_u._-2hT.-z-._7-5lL..-_--.VEa-_gn.8-c.C3_F._oX-FT
|
||||||
target:
|
target:
|
||||||
apiVersion: "48"
|
apiVersion: "49"
|
||||||
kind: "46"
|
kind: "47"
|
||||||
name: "47"
|
name: "48"
|
||||||
pods:
|
pods:
|
||||||
currentAverageValue: "878"
|
currentAverageValue: "400"
|
||||||
metricName: "56"
|
metricName: "57"
|
||||||
selector:
|
selector:
|
||||||
matchExpressions:
|
matchExpressions:
|
||||||
- key: g-..__._____K_g1cXfr.4_.B
|
- key: 26-k8-c2---2etfh41ca-z-5g2wco280.ka-6-31g--z-o-3bz6-8-0-1-z--271s-p9-8--m-cbck561-7n/VC..7o_x3..-.8J
|
||||||
operator: DoesNotExist
|
operator: NotIn
|
||||||
|
values:
|
||||||
|
- 8._Q.6.I--2_9.v.--_.--4QQ.-s.H.Hf
|
||||||
matchLabels:
|
matchLabels:
|
||||||
6fv--m-8--72-bca4m56au3f-j/0-_1-F.h-__k_K5._..O_.J_-G_--V-42E_--o90G_A4..-L..-__0N_N.O3i: r_gn.8-c.C3_F._oX-F9_.v
|
mj_9.M.134-5-.q6H_.--_---.M.U_-m.-P.yP9S--858LI__.8U: KrO-S-P_-...0c.-.p_3_J_SA995IKCR.s--f.-f.-zv._._.5-HT
|
||||||
resource:
|
resource:
|
||||||
currentAverageUtilization: -1607821167
|
currentAverageUtilization: 769521729
|
||||||
currentAverageValue: "832"
|
currentAverageValue: "727"
|
||||||
name: šeSvEȤƏ埮pɵ{WOŭW灬pȭ
|
name: ƻ遲njlȘ鹾KƂʼnç
|
||||||
type: ' ïì«丯Ƙ枛牐ɺ皚|懥'
|
type: ""
|
||||||
currentReplicas: 596942561
|
currentReplicas: -1462219068
|
||||||
desiredReplicas: -1880980172
|
desiredReplicas: -370386363
|
||||||
observedGeneration: -7224326297454280417
|
observedGeneration: 61436896663269868
|
||||||
|
@ -112,159 +112,169 @@
|
|||||||
"averageUtilization": 580681683
|
"averageUtilization": 580681683
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"containerResource": {
|
||||||
|
"name": "Ɋł/擇ɦĽ胚O醔ɍ厶耈 ",
|
||||||
|
"target": {
|
||||||
|
"type": "禒Ƙá腿ħ缶.蒅",
|
||||||
|
"value": "999",
|
||||||
|
"averageValue": "151",
|
||||||
|
"averageUtilization": -1105572246
|
||||||
|
},
|
||||||
|
"container": "39"
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
"metric": {
|
"metric": {
|
||||||
"name": "39",
|
"name": "40",
|
||||||
"selector": {
|
"selector": {
|
||||||
"matchLabels": {
|
"matchLabels": {
|
||||||
"9s-m---vl80.5-6y-07b-3---g-jdi/z_-tY-R6S17_.8CnK_O.d-._NwcGnP-w-Sf5_Or.i1_7z.WH-.._d": "1_57__JR.N-1zL-4--6o--Bo-F__..XR.7_1-l"
|
"wcGnP-w-Sf5_O1": "1_70"
|
||||||
},
|
},
|
||||||
"matchExpressions": [
|
"matchExpressions": [
|
||||||
{
|
{
|
||||||
"key": "n3-8d-0-5qty--4-p---u16-wv-i.84-n4f--139-295at-o7qff7-x--r7v66bm71u-n4f0/2_31.-.-yz-0-_p4mz--.I_f6kjsz-7lwY-Y93-x6bigm_-._q",
|
"key": "1-1-x1z-j4kh6oqu-or---40--87-1wp6.759s-3------6tv27r-m8w-6-9-35d383-iq-ay1z25-3-vj73d/Y.t--_0..--_6yV07-_.___gO-d.iUaCw",
|
||||||
"operator": "In",
|
"operator": "DoesNotExist"
|
||||||
"values": [
|
|
||||||
"Q3_Y.5.-..P_pDZ-._._t__2k"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "3.v-鿧悮坮Ȣ",
|
"type": "ʣy豎@ɀ羭,铻OŤ",
|
||||||
"value": "82",
|
"value": "830",
|
||||||
"averageValue": "301",
|
"averageValue": "799",
|
||||||
"averageUtilization": -521487971
|
"averageUtilization": 747521320
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"behavior": {
|
"behavior": {
|
||||||
"scaleUp": {
|
"scaleUp": {
|
||||||
"stabilizationWindowSeconds": 1761963371,
|
"stabilizationWindowSeconds": -648954478,
|
||||||
"selectPolicy": "0矀Kʝ瘴I\\p[ħsĨɆâĺɗŹ倗S",
|
"selectPolicy": "Ƿ裚瓶釆Ɗ+j忊",
|
||||||
"policies": [
|
"policies": [
|
||||||
{
|
{
|
||||||
"type": "嶗U",
|
"type": "ȫ焗捏ĨFħ籘Àǒɿʒ刽",
|
||||||
"value": -1285424066,
|
"value": 427196286,
|
||||||
"periodSeconds": -686523310
|
"periodSeconds": 1048864116
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"scaleDown": {
|
"scaleDown": {
|
||||||
"stabilizationWindowSeconds": 1206365825,
|
"stabilizationWindowSeconds": -342705708,
|
||||||
"selectPolicy": "/ɸɎ R§耶FfBls3!",
|
"selectPolicy": "褎weLJèux",
|
||||||
"policies": [
|
"policies": [
|
||||||
{
|
{
|
||||||
"type": "ɾģ毋Ó6dz娝嘚",
|
"type": "VƋZ1Ůđ眊ľǎɳ,ǿ飏",
|
||||||
"value": 627713162,
|
"value": 2040455355,
|
||||||
"periodSeconds": 1255312175
|
"periodSeconds": 1505972335
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"observedGeneration": -7477362499801752548,
|
"observedGeneration": -115578794491385044,
|
||||||
"currentReplicas": 267768240,
|
"currentReplicas": 474119379,
|
||||||
"desiredReplicas": -127849333,
|
"desiredReplicas": 1923334396,
|
||||||
"currentMetrics": [
|
"currentMetrics": [
|
||||||
{
|
{
|
||||||
"type": "Ǖɳɷ9Ì崟¿瘦ɖ緕",
|
"type": "0Ƹ[Ęİ榌U",
|
||||||
"object": {
|
"object": {
|
||||||
"metric": {
|
"metric": {
|
||||||
"name": "46",
|
"name": "47",
|
||||||
"selector": {
|
"selector": {
|
||||||
"matchLabels": {
|
"matchLabels": {
|
||||||
"29.-_Z.0_1._hg._o_p665O_4Gj._BXt.O-7___-Y_um-_8r--684._V": "8_...E.-o"
|
"hA9..9__Y-H-Mqpt._.-_..05c.---qy-_5_S.d5a3Jb": "46g_4....1..jtFe8b_A_..P1s-V.9.4..9..c_uo3Pa__n-Di"
|
||||||
},
|
},
|
||||||
"matchExpressions": [
|
"matchExpressions": [
|
||||||
{
|
{
|
||||||
"key": "6-d42--clo90---461v-07r--0---8-30i-uo/9DF",
|
"key": "Dp665O_4Gj._BXt.O-7___-Y_um-_8r--684._-_188",
|
||||||
"operator": "In",
|
"operator": "NotIn",
|
||||||
"values": [
|
"values": [
|
||||||
"2hT.-z-._7-5lL..-_--.VEa-_gn.8-c.C3_F._oX-F9_.5vN5.25aWx.a"
|
"XK5._..O_.J_-G_--V-42E_--o90G_A4..-L..-__0N_N.O30-_u._-2T"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"current": {
|
"current": {
|
||||||
"value": "526",
|
"value": "124",
|
||||||
"averageValue": "860",
|
"averageValue": "472",
|
||||||
"averageUtilization": -126958936
|
"averageUtilization": -1666319281
|
||||||
},
|
},
|
||||||
"describedObject": {
|
"describedObject": {
|
||||||
"kind": "53",
|
"kind": "54",
|
||||||
"name": "54",
|
"name": "55",
|
||||||
"apiVersion": "55"
|
"apiVersion": "56"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pods": {
|
"pods": {
|
||||||
"metric": {
|
"metric": {
|
||||||
"name": "56",
|
"name": "57",
|
||||||
"selector": {
|
"selector": {
|
||||||
"matchLabels": {
|
"matchLabels": {
|
||||||
"d5-g-7-7---g88w2k4usz--mj-8o26--26-hs5-jeds4-4tz9x-4.i-l11q5--uk5mj-94-8134i5k6q6--5tu-tie4-7--gm4p-8y-99/N_g-..__._____K_g1cXfr4": "ET_..3dCv3j._.-_pP__up.2L_s-o779._-k-N"
|
"5.-_--.VEa-_gn.8-c.3": "F._oX-F9_.5vN5.25aWx.2aM214_.-C"
|
||||||
},
|
},
|
||||||
"matchExpressions": [
|
"matchExpressions": [
|
||||||
{
|
{
|
||||||
"key": "382m88w-pz9d4i-m7---k8235--8--c83-4b-9-1k.1f-53-x1y-8---3----p-pdn--j2---2--82--cj-1-s--op3w/3--Z1Tvw39F_C-rtSY.g._2F7.-_e..Or_-.3OHgt.U",
|
"key": "4ds4-4tz9x--j.1l11q5--uk5mj-94-8134i5k6q6--5tu-tie4-7--gm4p-8y-9-te5/H._____K_g1cXfr.4_.-_-_-...1py_8-3..s._.x.2K_2qu_0S-CqWD",
|
||||||
"operator": "In",
|
"operator": "Exists"
|
||||||
"values": [
|
|
||||||
"y.8_8"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"current": {
|
"current": {
|
||||||
"value": "671",
|
"value": "378",
|
||||||
"averageValue": "683",
|
"averageValue": "328",
|
||||||
"averageUtilization": 1008425444
|
"averageUtilization": -1050824692
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"name": "Ƈè*鑏='ʨ|ǓÓ敆OɈÏ 瞍髃",
|
"name": "反-n覦灲閈誹ʅ蕉ɼ搳ǭ濑箨ʨ",
|
||||||
"current": {
|
"current": {
|
||||||
"value": "93",
|
"value": "113",
|
||||||
"averageValue": "183",
|
"averageValue": "653",
|
||||||
"averageUtilization": -392406530
|
"averageUtilization": 1190831814
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"containerResource": {
|
||||||
|
"name": "腂ǂǚŜEuEy",
|
||||||
|
"current": {
|
||||||
|
"value": "77",
|
||||||
|
"averageValue": "394",
|
||||||
|
"averageUtilization": -1945921250
|
||||||
|
},
|
||||||
|
"container": "64"
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
"metric": {
|
"metric": {
|
||||||
"name": "63",
|
"name": "65",
|
||||||
"selector": {
|
"selector": {
|
||||||
"matchLabels": {
|
"matchLabels": {
|
||||||
"627-23---g-----p8-d5-8-m8i--k0j5-gr-y7nlp97v-0-1y7/2....3_t_-l..-.DG7r-3.----._4__XOnf_ZN.-_--r.E__-8": "K.-miJ4x-_0_5-_7"
|
"Tvw39F_C-rtSY.g._2F7.-_e..Or_-.3OHgt._U.-x_rC9..__-6_k.N-2B_Ve": "fh4.caTz_.g.w-o.8_WT-M.3_-1y_8E"
|
||||||
},
|
},
|
||||||
"matchExpressions": [
|
"matchExpressions": [
|
||||||
{
|
{
|
||||||
"key": "c-.F5_x.KNC0-.-m_0-m-6Sp_N-S..o",
|
"key": "n_H-.___._D8.TS-jJ.Ys_Mop34_-2",
|
||||||
"operator": "In",
|
"operator": "DoesNotExist"
|
||||||
"values": [
|
|
||||||
"g-_4Q__-v_t_u_.__I_-_-3-3--5X1rh-K5y_AzOBW.9oE9_6.--v7"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"current": {
|
"current": {
|
||||||
"value": "287",
|
"value": "444",
|
||||||
"averageValue": "759",
|
"averageValue": "797",
|
||||||
"averageUtilization": -1175595426
|
"averageUtilization": 1928526133
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"conditions": [
|
"conditions": [
|
||||||
{
|
{
|
||||||
"type": "`翾'ųŎ群E牬庘颮6(|ǖû",
|
"type": "44矕",
|
||||||
"status": "龢ÄƤUǷ坒ŕF5o儎ĄÇ稕E",
|
"status": "ƱÁR»淹揀",
|
||||||
"lastTransitionTime": "2682-06-14T06:09:58Z",
|
"lastTransitionTime": "2026-05-26T09:35:23Z",
|
||||||
"reason": "70",
|
"reason": "72",
|
||||||
"message": "71"
|
"message": "73"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -33,36 +33,42 @@ spec:
|
|||||||
behavior:
|
behavior:
|
||||||
scaleDown:
|
scaleDown:
|
||||||
policies:
|
policies:
|
||||||
- periodSeconds: 1255312175
|
- periodSeconds: 1505972335
|
||||||
type: ɾģ毋Ó6dz娝嘚
|
type: VƋZ1Ůđ眊ľǎɳ,ǿ飏
|
||||||
value: 627713162
|
value: 2040455355
|
||||||
selectPolicy: /ɸɎ R§耶FfBls3!
|
selectPolicy: 褎weLJèux
|
||||||
stabilizationWindowSeconds: 1206365825
|
stabilizationWindowSeconds: -342705708
|
||||||
scaleUp:
|
scaleUp:
|
||||||
policies:
|
policies:
|
||||||
- periodSeconds: -686523310
|
- periodSeconds: 1048864116
|
||||||
type: 嶗U
|
type: ȫ焗捏ĨFħ籘Àǒɿʒ刽
|
||||||
value: -1285424066
|
value: 427196286
|
||||||
selectPolicy: 0矀Kʝ瘴I\p[ħsĨɆâĺɗŹ倗S
|
selectPolicy: Ƿ裚瓶釆Ɗ+j忊
|
||||||
stabilizationWindowSeconds: 1761963371
|
stabilizationWindowSeconds: -648954478
|
||||||
maxReplicas: -1971381490
|
maxReplicas: -1971381490
|
||||||
metrics:
|
metrics:
|
||||||
- external:
|
- containerResource:
|
||||||
|
container: "39"
|
||||||
|
name: Ɋł/擇ɦĽ胚O醔ɍ厶耈
|
||||||
|
target:
|
||||||
|
averageUtilization: -1105572246
|
||||||
|
averageValue: "151"
|
||||||
|
type: 禒Ƙá腿ħ缶.蒅
|
||||||
|
value: "999"
|
||||||
|
external:
|
||||||
metric:
|
metric:
|
||||||
name: "39"
|
name: "40"
|
||||||
selector:
|
selector:
|
||||||
matchExpressions:
|
matchExpressions:
|
||||||
- key: n3-8d-0-5qty--4-p---u16-wv-i.84-n4f--139-295at-o7qff7-x--r7v66bm71u-n4f0/2_31.-.-yz-0-_p4mz--.I_f6kjsz-7lwY-Y93-x6bigm_-._q
|
- key: 1-1-x1z-j4kh6oqu-or---40--87-1wp6.759s-3------6tv27r-m8w-6-9-35d383-iq-ay1z25-3-vj73d/Y.t--_0..--_6yV07-_.___gO-d.iUaCw
|
||||||
operator: In
|
operator: DoesNotExist
|
||||||
values:
|
|
||||||
- Q3_Y.5.-..P_pDZ-._._t__2k
|
|
||||||
matchLabels:
|
matchLabels:
|
||||||
9s-m---vl80.5-6y-07b-3---g-jdi/z_-tY-R6S17_.8CnK_O.d-._NwcGnP-w-Sf5_Or.i1_7z.WH-.._d: 1_57__JR.N-1zL-4--6o--Bo-F__..XR.7_1-l
|
wcGnP-w-Sf5_O1: "1_70"
|
||||||
target:
|
target:
|
||||||
averageUtilization: -521487971
|
averageUtilization: 747521320
|
||||||
averageValue: "301"
|
averageValue: "799"
|
||||||
type: 3.v-鿧悮坮Ȣ
|
type: ʣy豎@ɀ羭,铻OŤ
|
||||||
value: "82"
|
value: "830"
|
||||||
object:
|
object:
|
||||||
describedObject:
|
describedObject:
|
||||||
apiVersion: "24"
|
apiVersion: "24"
|
||||||
@ -112,69 +118,71 @@ spec:
|
|||||||
name: "20"
|
name: "20"
|
||||||
status:
|
status:
|
||||||
conditions:
|
conditions:
|
||||||
- lastTransitionTime: "2682-06-14T06:09:58Z"
|
- lastTransitionTime: "2026-05-26T09:35:23Z"
|
||||||
message: "71"
|
message: "73"
|
||||||
reason: "70"
|
reason: "72"
|
||||||
status: 龢ÄƤUǷ坒ŕF5o儎ĄÇ稕E
|
status: ƱÁR»淹揀
|
||||||
type: '`翾''ųŎ群E牬庘颮6(|ǖû'
|
type: 44矕
|
||||||
currentMetrics:
|
currentMetrics:
|
||||||
- external:
|
- containerResource:
|
||||||
|
container: "64"
|
||||||
current:
|
current:
|
||||||
averageUtilization: -1175595426
|
averageUtilization: -1945921250
|
||||||
averageValue: "759"
|
averageValue: "394"
|
||||||
value: "287"
|
value: "77"
|
||||||
|
name: 腂ǂǚŜEuEy
|
||||||
|
external:
|
||||||
|
current:
|
||||||
|
averageUtilization: 1928526133
|
||||||
|
averageValue: "797"
|
||||||
|
value: "444"
|
||||||
metric:
|
metric:
|
||||||
name: "63"
|
name: "65"
|
||||||
selector:
|
selector:
|
||||||
matchExpressions:
|
matchExpressions:
|
||||||
- key: c-.F5_x.KNC0-.-m_0-m-6Sp_N-S..o
|
- key: n_H-.___._D8.TS-jJ.Ys_Mop34_-2
|
||||||
operator: In
|
operator: DoesNotExist
|
||||||
values:
|
|
||||||
- g-_4Q__-v_t_u_.__I_-_-3-3--5X1rh-K5y_AzOBW.9oE9_6.--v7
|
|
||||||
matchLabels:
|
matchLabels:
|
||||||
627-23---g-----p8-d5-8-m8i--k0j5-gr-y7nlp97v-0-1y7/2....3_t_-l..-.DG7r-3.----._4__XOnf_ZN.-_--r.E__-8: K.-miJ4x-_0_5-_7
|
Tvw39F_C-rtSY.g._2F7.-_e..Or_-.3OHgt._U.-x_rC9..__-6_k.N-2B_Ve: fh4.caTz_.g.w-o.8_WT-M.3_-1y_8E
|
||||||
object:
|
object:
|
||||||
current:
|
current:
|
||||||
averageUtilization: -126958936
|
averageUtilization: -1666319281
|
||||||
averageValue: "860"
|
averageValue: "472"
|
||||||
value: "526"
|
value: "124"
|
||||||
describedObject:
|
describedObject:
|
||||||
apiVersion: "55"
|
apiVersion: "56"
|
||||||
kind: "53"
|
kind: "54"
|
||||||
name: "54"
|
name: "55"
|
||||||
metric:
|
metric:
|
||||||
name: "46"
|
name: "47"
|
||||||
selector:
|
selector:
|
||||||
matchExpressions:
|
matchExpressions:
|
||||||
- key: 6-d42--clo90---461v-07r--0---8-30i-uo/9DF
|
- key: Dp665O_4Gj._BXt.O-7___-Y_um-_8r--684._-_188
|
||||||
operator: In
|
operator: NotIn
|
||||||
values:
|
values:
|
||||||
- 2hT.-z-._7-5lL..-_--.VEa-_gn.8-c.C3_F._oX-F9_.5vN5.25aWx.a
|
- XK5._..O_.J_-G_--V-42E_--o90G_A4..-L..-__0N_N.O30-_u._-2T
|
||||||
matchLabels:
|
matchLabels:
|
||||||
29.-_Z.0_1._hg._o_p665O_4Gj._BXt.O-7___-Y_um-_8r--684._V: 8_...E.-o
|
hA9..9__Y-H-Mqpt._.-_..05c.---qy-_5_S.d5a3Jb: 46g_4....1..jtFe8b_A_..P1s-V.9.4..9..c_uo3Pa__n-Di
|
||||||
pods:
|
pods:
|
||||||
current:
|
current:
|
||||||
averageUtilization: 1008425444
|
averageUtilization: -1050824692
|
||||||
averageValue: "683"
|
averageValue: "328"
|
||||||
value: "671"
|
value: "378"
|
||||||
metric:
|
metric:
|
||||||
name: "56"
|
name: "57"
|
||||||
selector:
|
selector:
|
||||||
matchExpressions:
|
matchExpressions:
|
||||||
- key: 382m88w-pz9d4i-m7---k8235--8--c83-4b-9-1k.1f-53-x1y-8---3----p-pdn--j2---2--82--cj-1-s--op3w/3--Z1Tvw39F_C-rtSY.g._2F7.-_e..Or_-.3OHgt.U
|
- key: 4ds4-4tz9x--j.1l11q5--uk5mj-94-8134i5k6q6--5tu-tie4-7--gm4p-8y-9-te5/H._____K_g1cXfr.4_.-_-_-...1py_8-3..s._.x.2K_2qu_0S-CqWD
|
||||||
operator: In
|
operator: Exists
|
||||||
values:
|
|
||||||
- y.8_8
|
|
||||||
matchLabels:
|
matchLabels:
|
||||||
? d5-g-7-7---g88w2k4usz--mj-8o26--26-hs5-jeds4-4tz9x-4.i-l11q5--uk5mj-94-8134i5k6q6--5tu-tie4-7--gm4p-8y-99/N_g-..__._____K_g1cXfr4
|
5.-_--.VEa-_gn.8-c.3: F._oX-F9_.5vN5.25aWx.2aM214_.-C
|
||||||
: ET_..3dCv3j._.-_pP__up.2L_s-o779._-k-N
|
|
||||||
resource:
|
resource:
|
||||||
current:
|
current:
|
||||||
averageUtilization: -392406530
|
averageUtilization: 1190831814
|
||||||
averageValue: "183"
|
averageValue: "653"
|
||||||
value: "93"
|
value: "113"
|
||||||
name: Ƈè*鑏='ʨ|ǓÓ敆OɈÏ 瞍髃
|
name: 反-n覦灲閈誹ʅ蕉ɼ搳ǭ濑箨ʨ
|
||||||
type: Ǖɳɷ9Ì崟¿瘦ɖ緕
|
type: 0Ƹ[Ęİ榌U
|
||||||
currentReplicas: 267768240
|
currentReplicas: 474119379
|
||||||
desiredReplicas: -127849333
|
desiredReplicas: 1923334396
|
||||||
observedGeneration: -7477362499801752548
|
observedGeneration: -115578794491385044
|
||||||
|
@ -30,6 +30,8 @@ import (
|
|||||||
|
|
||||||
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
||||||
return map[string]common.OpenAPIDefinition{
|
return map[string]common.OpenAPIDefinition{
|
||||||
|
"k8s.io/api/autoscaling/v1.ContainerResourceMetricSource": schema_k8sio_api_autoscaling_v1_ContainerResourceMetricSource(ref),
|
||||||
|
"k8s.io/api/autoscaling/v1.ContainerResourceMetricStatus": schema_k8sio_api_autoscaling_v1_ContainerResourceMetricStatus(ref),
|
||||||
"k8s.io/api/autoscaling/v1.CrossVersionObjectReference": schema_k8sio_api_autoscaling_v1_CrossVersionObjectReference(ref),
|
"k8s.io/api/autoscaling/v1.CrossVersionObjectReference": schema_k8sio_api_autoscaling_v1_CrossVersionObjectReference(ref),
|
||||||
"k8s.io/api/autoscaling/v1.ExternalMetricSource": schema_k8sio_api_autoscaling_v1_ExternalMetricSource(ref),
|
"k8s.io/api/autoscaling/v1.ExternalMetricSource": schema_k8sio_api_autoscaling_v1_ExternalMetricSource(ref),
|
||||||
"k8s.io/api/autoscaling/v1.ExternalMetricStatus": schema_k8sio_api_autoscaling_v1_ExternalMetricStatus(ref),
|
"k8s.io/api/autoscaling/v1.ExternalMetricStatus": schema_k8sio_api_autoscaling_v1_ExternalMetricStatus(ref),
|
||||||
@ -104,6 +106,92 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func schema_k8sio_api_autoscaling_v1_ContainerResourceMetricSource(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in the requests and limits, describing a single container in each of the pods of the current scale target(e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built into Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.",
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"name": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "name is the name of the resource in question.",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"targetAverageUtilization": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "targetAverageUtilization is the target value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.",
|
||||||
|
Type: []string{"integer"},
|
||||||
|
Format: "int32",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"targetAverageValue": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type.",
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"container": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "container is the name of the container in the pods of the scaling target.",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Required: []string{"name", "container"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"k8s.io/apimachinery/pkg/api/resource.Quantity"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func schema_k8sio_api_autoscaling_v1_ContainerResourceMetricStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"name": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "name is the name of the resource in question.",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"currentAverageUtilization": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods. It will only be present if `targetAverageValue` was set in the corresponding metric specification.",
|
||||||
|
Type: []string{"integer"},
|
||||||
|
Format: "int32",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"currentAverageValue": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "currentAverageValue is the current value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type. It will always be set, regardless of the corresponding metric specification.",
|
||||||
|
Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"container": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "container is the name of the container in the pods of the scaling taget",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Required: []string{"name", "currentAverageValue", "container"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: []string{
|
||||||
|
"k8s.io/apimachinery/pkg/api/resource.Quantity"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func schema_k8sio_api_autoscaling_v1_CrossVersionObjectReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
func schema_k8sio_api_autoscaling_v1_CrossVersionObjectReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
return common.OpenAPIDefinition{
|
return common.OpenAPIDefinition{
|
||||||
Schema: spec.Schema{
|
Schema: spec.Schema{
|
||||||
@ -469,7 +557,7 @@ func schema_k8sio_api_autoscaling_v1_MetricSpec(ref common.ReferenceCallback) co
|
|||||||
Properties: map[string]spec.Schema{
|
Properties: map[string]spec.Schema{
|
||||||
"type": {
|
"type": {
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Description: "type is the type of metric source. It should be one of \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object.",
|
Description: "type is the type of metric source. It should be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
Type: []string{"string"},
|
Type: []string{"string"},
|
||||||
Format: "",
|
Format: "",
|
||||||
},
|
},
|
||||||
@ -492,6 +580,12 @@ func schema_k8sio_api_autoscaling_v1_MetricSpec(ref common.ReferenceCallback) co
|
|||||||
Ref: ref("k8s.io/api/autoscaling/v1.ResourceMetricSource"),
|
Ref: ref("k8s.io/api/autoscaling/v1.ResourceMetricSource"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"containerResource": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.",
|
||||||
|
Ref: ref("k8s.io/api/autoscaling/v1.ContainerResourceMetricSource"),
|
||||||
|
},
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Description: "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
Description: "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
||||||
@ -503,7 +597,7 @@ func schema_k8sio_api_autoscaling_v1_MetricSpec(ref common.ReferenceCallback) co
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Dependencies: []string{
|
Dependencies: []string{
|
||||||
"k8s.io/api/autoscaling/v1.ExternalMetricSource", "k8s.io/api/autoscaling/v1.ObjectMetricSource", "k8s.io/api/autoscaling/v1.PodsMetricSource", "k8s.io/api/autoscaling/v1.ResourceMetricSource"},
|
"k8s.io/api/autoscaling/v1.ContainerResourceMetricSource", "k8s.io/api/autoscaling/v1.ExternalMetricSource", "k8s.io/api/autoscaling/v1.ObjectMetricSource", "k8s.io/api/autoscaling/v1.PodsMetricSource", "k8s.io/api/autoscaling/v1.ResourceMetricSource"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +610,7 @@ func schema_k8sio_api_autoscaling_v1_MetricStatus(ref common.ReferenceCallback)
|
|||||||
Properties: map[string]spec.Schema{
|
Properties: map[string]spec.Schema{
|
||||||
"type": {
|
"type": {
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Description: "type is the type of metric source. It will be one of \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.",
|
Description: "type is the type of metric source. It will be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object. Note: \"ContainerResource\" type is available on when the feature-gate HPAContainerMetrics is enabled",
|
||||||
Type: []string{"string"},
|
Type: []string{"string"},
|
||||||
Format: "",
|
Format: "",
|
||||||
},
|
},
|
||||||
@ -539,6 +633,12 @@ func schema_k8sio_api_autoscaling_v1_MetricStatus(ref common.ReferenceCallback)
|
|||||||
Ref: ref("k8s.io/api/autoscaling/v1.ResourceMetricStatus"),
|
Ref: ref("k8s.io/api/autoscaling/v1.ResourceMetricStatus"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"containerResource": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.",
|
||||||
|
Ref: ref("k8s.io/api/autoscaling/v1.ContainerResourceMetricStatus"),
|
||||||
|
},
|
||||||
|
},
|
||||||
"external": {
|
"external": {
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Description: "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
Description: "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).",
|
||||||
@ -550,7 +650,7 @@ func schema_k8sio_api_autoscaling_v1_MetricStatus(ref common.ReferenceCallback)
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Dependencies: []string{
|
Dependencies: []string{
|
||||||
"k8s.io/api/autoscaling/v1.ExternalMetricStatus", "k8s.io/api/autoscaling/v1.ObjectMetricStatus", "k8s.io/api/autoscaling/v1.PodsMetricStatus", "k8s.io/api/autoscaling/v1.ResourceMetricStatus"},
|
"k8s.io/api/autoscaling/v1.ContainerResourceMetricStatus", "k8s.io/api/autoscaling/v1.ExternalMetricStatus", "k8s.io/api/autoscaling/v1.ObjectMetricStatus", "k8s.io/api/autoscaling/v1.PodsMetricStatus", "k8s.io/api/autoscaling/v1.ResourceMetricStatus"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3653,6 +3653,26 @@ func describeHorizontalPodAutoscalerV2beta2(hpa *autoscalingv2beta2.HorizontalPo
|
|||||||
}
|
}
|
||||||
w.Write(LEVEL_1, "(as a percentage of request):\t%s / %s\n", current, target)
|
w.Write(LEVEL_1, "(as a percentage of request):\t%s / %s\n", current, target)
|
||||||
}
|
}
|
||||||
|
case autoscalingv2beta2.ContainerResourceMetricSourceType:
|
||||||
|
w.Write(LEVEL_1, "resource %s of container \"%s\" on pods", string(metric.ContainerResource.Name), metric.ContainerResource.Container)
|
||||||
|
if metric.ContainerResource.Target.AverageValue != nil {
|
||||||
|
current := "<unknown>"
|
||||||
|
if len(hpa.Status.CurrentMetrics) > i && hpa.Status.CurrentMetrics[i].ContainerResource != nil {
|
||||||
|
current = hpa.Status.CurrentMetrics[i].ContainerResource.Current.AverageValue.String()
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_0, ":\t%s / %s\n", current, metric.ContainerResource.Target.AverageValue.String())
|
||||||
|
} else {
|
||||||
|
current := "<unknown>"
|
||||||
|
if len(hpa.Status.CurrentMetrics) > i && hpa.Status.CurrentMetrics[i].ContainerResource != nil && hpa.Status.CurrentMetrics[i].ContainerResource.Current.AverageUtilization != nil {
|
||||||
|
current = fmt.Sprintf("%d%% (%s)", *hpa.Status.CurrentMetrics[i].ContainerResource.Current.AverageUtilization, hpa.Status.CurrentMetrics[i].ContainerResource.Current.AverageValue.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
target := "<auto>"
|
||||||
|
if metric.ContainerResource.Target.AverageUtilization != nil {
|
||||||
|
target = fmt.Sprintf("%d%%", *metric.ContainerResource.Target.AverageUtilization)
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_1, "(as a percentage of request):\t%s / %s\n", current, target)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
w.Write(LEVEL_1, "<unknown metric type %q>\n", string(metric.Type))
|
w.Write(LEVEL_1, "<unknown metric type %q>\n", string(metric.Type))
|
||||||
}
|
}
|
||||||
|
@ -2711,6 +2711,152 @@ func TestDescribeHorizontalPodAutoscaler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"container resource source type, target average value (no current)",
|
||||||
|
autoscalingv2beta2.HorizontalPodAutoscaler{
|
||||||
|
Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscalingv2beta2.CrossVersionObjectReference{
|
||||||
|
Name: "some-rc",
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
},
|
||||||
|
MinReplicas: &minReplicasVal,
|
||||||
|
MaxReplicas: 10,
|
||||||
|
Metrics: []autoscalingv2beta2.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscalingv2beta2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2beta2.ContainerResourceMetricSource{
|
||||||
|
Name: corev1.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Target: autoscalingv2beta2.MetricTarget{
|
||||||
|
Type: autoscalingv2beta2.AverageValueMetricType,
|
||||||
|
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscalingv2beta2.HorizontalPodAutoscalerStatus{
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
DesiredReplicas: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"container resource source type, target average value (with current)",
|
||||||
|
autoscalingv2beta2.HorizontalPodAutoscaler{
|
||||||
|
Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscalingv2beta2.CrossVersionObjectReference{
|
||||||
|
Name: "some-rc",
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
},
|
||||||
|
MinReplicas: &minReplicasVal,
|
||||||
|
MaxReplicas: 10,
|
||||||
|
Metrics: []autoscalingv2beta2.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscalingv2beta2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2beta2.ContainerResourceMetricSource{
|
||||||
|
Name: corev1.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Target: autoscalingv2beta2.MetricTarget{
|
||||||
|
Type: autoscalingv2beta2.AverageValueMetricType,
|
||||||
|
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscalingv2beta2.HorizontalPodAutoscalerStatus{
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
DesiredReplicas: 5,
|
||||||
|
CurrentMetrics: []autoscalingv2beta2.MetricStatus{
|
||||||
|
{
|
||||||
|
Type: autoscalingv2beta2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2beta2.ContainerResourceMetricStatus{
|
||||||
|
Name: corev1.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Current: autoscalingv2beta2.MetricValueStatus{
|
||||||
|
AverageValue: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"container resource source type, target utilization (no current)",
|
||||||
|
autoscalingv2beta2.HorizontalPodAutoscaler{
|
||||||
|
Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscalingv2beta2.CrossVersionObjectReference{
|
||||||
|
Name: "some-rc",
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
},
|
||||||
|
MinReplicas: &minReplicasVal,
|
||||||
|
MaxReplicas: 10,
|
||||||
|
Metrics: []autoscalingv2beta2.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscalingv2beta2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2beta2.ContainerResourceMetricSource{
|
||||||
|
Name: corev1.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Target: autoscalingv2beta2.MetricTarget{
|
||||||
|
Type: autoscalingv2beta2.UtilizationMetricType,
|
||||||
|
AverageUtilization: &targetUtilizationVal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscalingv2beta2.HorizontalPodAutoscalerStatus{
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
DesiredReplicas: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"container resource source type, target utilization (with current)",
|
||||||
|
autoscalingv2beta2.HorizontalPodAutoscaler{
|
||||||
|
Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
|
||||||
|
ScaleTargetRef: autoscalingv2beta2.CrossVersionObjectReference{
|
||||||
|
Name: "some-rc",
|
||||||
|
Kind: "ReplicationController",
|
||||||
|
},
|
||||||
|
MinReplicas: &minReplicasVal,
|
||||||
|
MaxReplicas: 10,
|
||||||
|
Metrics: []autoscalingv2beta2.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscalingv2beta2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2beta2.ContainerResourceMetricSource{
|
||||||
|
Name: corev1.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Target: autoscalingv2beta2.MetricTarget{
|
||||||
|
Type: autoscalingv2beta2.UtilizationMetricType,
|
||||||
|
AverageUtilization: &targetUtilizationVal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscalingv2beta2.HorizontalPodAutoscalerStatus{
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
DesiredReplicas: 5,
|
||||||
|
CurrentMetrics: []autoscalingv2beta2.MetricStatus{
|
||||||
|
{
|
||||||
|
Type: autoscalingv2beta2.ContainerResourceMetricSourceType,
|
||||||
|
ContainerResource: &autoscalingv2beta2.ContainerResourceMetricStatus{
|
||||||
|
Name: corev1.ResourceCPU,
|
||||||
|
Container: "application",
|
||||||
|
Current: autoscalingv2beta2.MetricValueStatus{
|
||||||
|
AverageUtilization: ¤tUtilizationVal,
|
||||||
|
AverageValue: resource.NewMilliQuantity(40, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"multiple metrics",
|
"multiple metrics",
|
||||||
autoscalingv2beta2.HorizontalPodAutoscaler{
|
autoscalingv2beta2.HorizontalPodAutoscaler{
|
||||||
|
Loading…
Reference in New Issue
Block a user