diff --git a/multidimensional-pod-autoscaler/deploy/download-deps.sh b/multidimensional-pod-autoscaler/deploy/download-deps.sh deleted file mode 100755 index fe96e9ca9b2e..000000000000 --- a/multidimensional-pod-autoscaler/deploy/download-deps.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -VERSION=${1#"v"} -if [ -z "$VERSION" ]; then - echo "Please specify the Kubernetes version: e.g." - echo "./download-deps.sh v1.21.0" - exit 1 -fi - -set -euo pipefail - -# Find out all the replaced imports, make a list of them. -MODS=($( - curl -sS "https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod" | - sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' -)) - -echo "MODS: $MODS" - -# Now add those similar replace statements in the local go.mod file, but first find the version that -# the Kubernetes is using for them. -for MOD in "${MODS[@]}"; do - V=$( - go mod download -json "${MOD}@kubernetes-${VERSION}" | - sed -n 's|.*"Version": "\(.*\)".*|\1|p' - ) - - echo "go mod edit ... ${MOD}" - go mod edit "-replace=${MOD}=${MOD}@${V}" -done - -go get "k8s.io/kubernetes@v${VERSION}" -go mod download diff --git a/multidimensional-pod-autoscaler/deploy/mpa-v1alpha1-crd-gen.yaml b/multidimensional-pod-autoscaler/deploy/mpa-v1alpha1-crd-gen.yaml index e28e494df655..1b29e20788fc 100644 --- a/multidimensional-pod-autoscaler/deploy/mpa-v1alpha1-crd-gen.yaml +++ b/multidimensional-pod-autoscaler/deploy/mpa-v1alpha1-crd-gen.yaml @@ -1,216 +1,10 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes/kubernetes/pull/63797 - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: "2022-10-11T07:35:27Z" - name: verticalpodautoscalercheckpoints.autoscaling.k8s.io -spec: - group: autoscaling.k8s.io - names: - kind: VerticalPodAutoscalerCheckpoint - listKind: VerticalPodAutoscalerCheckpointList - plural: verticalpodautoscalercheckpoints - shortNames: - - vpacheckpoint - singular: verticalpodautoscalercheckpoint - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: VerticalPodAutoscalerCheckpoint is the checkpoint of the internal - state of VPA that is used for recovery after recommender's restart. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: 'Specification of the checkpoint. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status.' - properties: - containerName: - description: Name of the checkpointed container. - type: string - vpaObjectName: - description: Name of the VPA object that stored VerticalPodAutoscalerCheckpoint - object. - type: string - type: object - status: - description: Data of the checkpoint. - properties: - cpuHistogram: - description: Checkpoint of histogram for consumption of CPU. - properties: - bucketWeights: - description: Map from bucket index to bucket weight. - type: object - x-kubernetes-preserve-unknown-fields: true - referenceTimestamp: - description: Reference timestamp for samples collected within - this histogram. - format: date-time - nullable: true - type: string - totalWeight: - description: Sum of samples to be used as denominator for weights - from BucketWeights. - type: number - type: object - firstSampleStart: - description: Timestamp of the fist sample from the histograms. - format: date-time - nullable: true - type: string - lastSampleStart: - description: Timestamp of the last sample from the histograms. - format: date-time - nullable: true - type: string - lastUpdateTime: - description: The time when the status was last refreshed. - format: date-time - nullable: true - type: string - memoryHistogram: - description: Checkpoint of histogram for consumption of memory. - properties: - bucketWeights: - description: Map from bucket index to bucket weight. - type: object - x-kubernetes-preserve-unknown-fields: true - referenceTimestamp: - description: Reference timestamp for samples collected within - this histogram. - format: date-time - nullable: true - type: string - totalWeight: - description: Sum of samples to be used as denominator for weights - from BucketWeights. - type: number - type: object - totalSamplesCount: - description: Total number of samples in the histograms. - type: integer - version: - description: Version of the format of the stored data. - type: string - type: object - type: object - served: true - storage: true - - name: v1beta2 - schema: - openAPIV3Schema: - description: VerticalPodAutoscalerCheckpoint is the checkpoint of the internal - state of VPA that is used for recovery after recommender's restart. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: 'Specification of the checkpoint. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status.' - properties: - containerName: - description: Name of the checkpointed container. - type: string - vpaObjectName: - description: Name of the VPA object that stored VerticalPodAutoscalerCheckpoint - object. - type: string - type: object - status: - description: Data of the checkpoint. - properties: - cpuHistogram: - description: Checkpoint of histogram for consumption of CPU. - properties: - bucketWeights: - description: Map from bucket index to bucket weight. - type: object - x-kubernetes-preserve-unknown-fields: true - referenceTimestamp: - description: Reference timestamp for samples collected within - this histogram. - format: date-time - nullable: true - type: string - totalWeight: - description: Sum of samples to be used as denominator for weights - from BucketWeights. - type: number - type: object - firstSampleStart: - description: Timestamp of the fist sample from the histograms. - format: date-time - nullable: true - type: string - lastSampleStart: - description: Timestamp of the last sample from the histograms. - format: date-time - nullable: true - type: string - lastUpdateTime: - description: The time when the status was last refreshed. - format: date-time - nullable: true - type: string - memoryHistogram: - description: Checkpoint of histogram for consumption of memory. - properties: - bucketWeights: - description: Map from bucket index to bucket weight. - type: object - x-kubernetes-preserve-unknown-fields: true - referenceTimestamp: - description: Reference timestamp for samples collected within - this histogram. - format: date-time - nullable: true - type: string - totalWeight: - description: Sum of samples to be used as denominator for weights - from BucketWeights. - type: number - type: object - totalSamplesCount: - description: Total number of samples in the histograms. - type: integer - version: - description: Version of the format of the stored data. - type: string - type: object - type: object - served: true - storage: false --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes/kubernetes/pull/63797 - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: "2022-10-11T07:35:27Z" + controller-gen.kubebuilder.io/version: v0.14.0 name: multidimpodautoscalers.autoscaling.k8s.io spec: group: autoscaling.k8s.io @@ -242,34 +36,724 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: MultidimPodAutoscaler is the configuration for a multi-dimensional pod - autoscaler, which automatically manages pod resources based on historical - and real time resource utilization. + description: |- + MultidimPodAutoscaler is the configuration for a multidimensional pod autoscaler, + which automatically manages pod resources and number of replicas based on historical and + real-time resource utilization as well as workload performance. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object spec: - description: 'Specification of the behavior of the autoscaler. More info: - https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status.' + description: |- + Specification of the behavior of the autoscaler. + More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status. properties: + constraints: + description: Describes the constraints for horizontal and vertical + scaling. + properties: + container: + description: Per-container resource policies. + items: + description: VerticalScalingConstraints describes the constraints + for vertical scaling. + properties: + mode: + description: Whether autoscaler is enabled for the container. + The default is "Auto". + enum: + - Auto + - "Off" + type: string + name: + description: Name of the container. + type: string + requests: + description: Describes the vertical scaling limits. + properties: + maxAllowed: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Specifies the maximum amount of resources that will be recommended + for the container. The default is no maximum. + type: object + minAllowed: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Specifies the minimal amount of resources that will be recommended + for the container. The default is no minimum. + type: object + type: object + type: object + type: array + containerControlledResources: + description: |- + Defines controlled resources. + If not specified, the default of [cpu, memory] will be used. + items: + description: ResourceName is the name identifying various resources + in a ResourceList. + type: string + type: array + global: + description: HorizontalScalingConstraints describes the constraints + for horizontal scaling. + properties: + behavior: + description: |- + Behavior configures the scaling behavior of the target in both Up and Down direction + (scaleUp and scaleDown fields respectively). + properties: + scaleDown: + description: |- + scaleDown is scaling policy for scaling Down. + If not set, the default value is to allow to scale down to minReplicas pods, with a + 300 second stabilization window (i.e., the highest recommendation for + the last 300sec is used). + properties: + policies: + description: |- + policies is a list of potential scaling polices which can be used during scaling. + At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid + items: + description: HPAScalingPolicy is a single policy + which must hold true for a specified past interval. + properties: + periodSeconds: + description: |- + periodSeconds specifies the window of time for which the policy should hold true. + PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). + format: int32 + type: integer + type: + description: type is used to specify the scaling + policy. + type: string + value: + description: |- + value contains the amount of change which is permitted by the policy. + It must be greater than zero + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + description: |- + selectPolicy is used to specify which policy should be used. + If not set, the default value Max is used. + type: string + stabilizationWindowSeconds: + description: |- + stabilizationWindowSeconds is the number of seconds for which past recommendations should be + considered while scaling up or scaling down. + StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). + If not set, use the default values: + - For scale up: 0 (i.e. no stabilization is done). + - For scale down: 300 (i.e. the stabilization window is 300 seconds long). + format: int32 + type: integer + type: object + scaleUp: + description: |- + scaleUp is scaling policy for scaling Up. + If not set, the default value is the higher of: + * increase no more than 4 pods per 60 seconds + * double the number of pods per 60 seconds + No stabilization is used. + properties: + policies: + description: |- + policies is a list of potential scaling polices which can be used during scaling. + At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid + items: + description: HPAScalingPolicy is a single policy + which must hold true for a specified past interval. + properties: + periodSeconds: + description: |- + periodSeconds specifies the window of time for which the policy should hold true. + PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). + format: int32 + type: integer + type: + description: type is used to specify the scaling + policy. + type: string + value: + description: |- + value contains the amount of change which is permitted by the policy. + It must be greater than zero + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + description: |- + selectPolicy is used to specify which policy should be used. + If not set, the default value Max is used. + type: string + stabilizationWindowSeconds: + description: |- + stabilizationWindowSeconds is the number of seconds for which past recommendations should be + considered while scaling up or scaling down. + StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). + If not set, use the default values: + - For scale up: 0 (i.e. no stabilization is done). + - For scale down: 300 (i.e. the stabilization window is 300 seconds long). + format: int32 + type: integer + type: object + type: object + maxReplicas: + description: |- + Upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than + MinReplicas. + format: int32 + type: integer + minReplicas: + description: Lower limit for the number of pods that can be + set by the autoscaler, default 1. + format: int32 + type: integer + required: + - maxReplicas + type: object + type: object + goals: + description: Describes the goals for autoscaling + properties: + metrics: + description: |- + Contains the specifications about the metric type and target in terms of resource + utilization or workload performance. See the individual metric source types for + more information about how each type of metric must respond. + items: + description: |- + MetricSpec specifies how to scale based on a single metric + (only `type` and one other matching field should be set at once). + properties: + containerResource: + description: |- + 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. + This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag. + 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: + description: target specifies the target value for the + given metric + properties: + averageUtilization: + description: |- + averageUtilization 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. + Currently only valid for Resource metric source type + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + description: |- + averageValue is the target value of the average of the + metric across all relevant pods (as a quantity) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + description: type represents whether the metric + type is Utilization, Value, or AverageValue + type: string + value: + anyOf: + - type: integer + - type: string + description: value is the target value of the metric + (as a quantity). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - container + - name + - target + type: object + external: + 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). + properties: + metric: + description: metric identifies the target metric by + name and selector + properties: + name: + description: name is the name of the given metric + type: string + selector: + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. + When unset, just the metricName will be used to gather metrics. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + description: target specifies the target value for the + given metric + properties: + averageUtilization: + description: |- + averageUtilization 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. + Currently only valid for Resource metric source type + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + description: |- + averageValue is the target value of the average of the + metric across all relevant pods (as a quantity) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + description: type represents whether the metric + type is Utilization, Value, or AverageValue + type: string + value: + anyOf: + - type: integer + - type: string + description: value is the target value of the metric + (as a quantity). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + object: + description: |- + object refers to a metric describing a single kubernetes object + (for example, hits-per-second on an Ingress object). + properties: + describedObject: + description: describedObject specifies the descriptions + of a object,such as kind,name apiVersion + properties: + apiVersion: + description: apiVersion is the API version of the + referent + type: string + kind: + description: 'kind is the kind of the referent; + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'name is the name of the referent; + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + required: + - kind + - name + type: object + metric: + description: metric identifies the target metric by + name and selector + properties: + name: + description: name is the name of the given metric + type: string + selector: + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. + When unset, just the metricName will be used to gather metrics. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + description: target specifies the target value for the + given metric + properties: + averageUtilization: + description: |- + averageUtilization 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. + Currently only valid for Resource metric source type + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + description: |- + averageValue is the target value of the average of the + metric across all relevant pods (as a quantity) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + description: type represents whether the metric + type is Utilization, Value, or AverageValue + type: string + value: + anyOf: + - type: integer + - type: string + description: value is the target value of the metric + (as a quantity). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - describedObject + - metric + - target + type: object + pods: + description: |- + 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. + properties: + metric: + description: metric identifies the target metric by + name and selector + properties: + name: + description: name is the name of the given metric + type: string + selector: + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. + When unset, just the metricName will be used to gather metrics. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + description: target specifies the target value for the + given metric + properties: + averageUtilization: + description: |- + averageUtilization 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. + Currently only valid for Resource metric source type + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + description: |- + averageValue is the target value of the average of the + metric across all relevant pods (as a quantity) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + description: type represents whether the metric + type is Utilization, Value, or AverageValue + type: string + value: + anyOf: + - type: integer + - type: string + description: value is the target value of the metric + (as a quantity). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + resource: + 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. + properties: + name: + description: name is the name of the resource in question. + type: string + target: + description: target specifies the target value for the + given metric + properties: + averageUtilization: + description: |- + averageUtilization 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. + Currently only valid for Resource metric source type + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + description: |- + averageValue is the target value of the average of the + metric across all relevant pods (as a quantity) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + description: type represents whether the metric + type is Utilization, Value, or AverageValue + type: string + value: + anyOf: + - type: integer + - type: string + description: value is the target value of the metric + (as a quantity). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - name + - target + type: object + type: + 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 + required: + - type + type: object + type: array + x-kubernetes-list-type: atomic + type: object + policy: + description: |- + Describes the rules on how changes are applied to the pods. + If not specified, all fields in the `PodUpdatePolicy` are set to their default values. + properties: + updateMode: + description: |- + Controls when autoscaler applies changes to the pod resources. + The default is 'Auto'. + enum: + - "Off" + - Initial + - Recreate + - Auto + type: string + type: object recommenders: - description: Recommender responsible for generating recommendation - for this object. List should be empty (then the default recommender - will generate the recommendation) or contain exactly one recommender. + description: |- + Recommender responsible for generating recommendation for the set of pods and the deployment. + List should be empty (then the default recommender will be used) or contain exactly one + recommender. items: - description: MultidimPodAutoscalerRecommenderSelector points to - a specific Multi-dimensional Pod Autoscaler recommender. In the future - it might pass parameters to the recommender. + description: |- + MultidimPodAutoscalerRecommenderSelector points to a specific Multidimensional Pod Autoscaler + recommender. + In the future it might pass parameters to the recommender. properties: name: description: Name of the recommender responsible for generating @@ -280,35 +764,38 @@ spec: type: object type: array resourcePolicy: - description: Controls how the autoscaler computes recommended resources. - The resource policy may be used to set constraints on the recommendations - for individual containers. If not specified, the autoscaler computes - recommended resources for all containers in the pod, without additional - constraints. + description: |- + Controls how the VPA autoscaler computes recommended resources. + The resource policy is also used to set constraints on the recommendations for individual + containers. If not specified, the autoscaler computes recommended resources for all + containers in the pod, without additional constraints. properties: containerPolicies: description: Per-container resource policies. items: - description: ContainerResourcePolicy controls how autoscaler - computes the recommended resources for a specific container. + description: |- + ContainerResourcePolicy controls how autoscaler computes the recommended + resources for a specific container. properties: containerName: - description: Name of the container or DefaultContainerResourcePolicy, - in which case the policy is used by the containers that - don't have their own policy specified. + description: |- + Name of the container or DefaultContainerResourcePolicy, in which + case the policy is used by the containers that don't have their own + policy specified. type: string controlledResources: - description: Specifies the type of recommendations that - will be computed (and possibly applied) by MPA. If not - specified, the default of [ResourceCPU, ResourceMemory] - will be used. + description: |- + Specifies the type of recommendations that will be computed + (and possibly applied) by VPA. + If not specified, the default of [ResourceCPU, ResourceMemory] will be used. items: description: ResourceName is the name identifying various resources in a ResourceList. type: string type: array controlledValues: - description: Specifies which resource values should be controlled. + description: |- + Specifies which resource values should be controlled. The default is "RequestsAndLimits". enum: - RequestsAndLimits @@ -321,9 +808,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: Specifies the maximum amount of resources that - will be recommended for the container. The default is - no maximum. + description: |- + Specifies the maximum amount of resources that will be recommended + for the container. The default is no maximum. type: object minAllowed: additionalProperties: @@ -332,9 +819,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: Specifies the minimal amount of resources that - will be recommended for the container. The default is - no minimum. + description: |- + Specifies the minimal amount of resources that will be recommended + for the container. The default is no minimum. type: object mode: description: Whether autoscaler is enabled for the container. @@ -347,408 +834,28 @@ spec: type: array type: object scaleTargetRef: - description: ScaleTargetRef points to the controller managing the set of - pods for the autoscaler to control - e.g., Deployment, StatefulSet. - MultidimPodAutoscaler can be targeted at controller implementing - scale subresource (the pod set is retrieved from the controller's - ScaleStatus) or some well known controllers (e.g. for DaemonSet - the pod set is read from the controller's spec). If MultidimPodAutoscaler - cannot use specified target it will report ConfigUnsupported condition. - Note that MultidimPodAutoscaler does not require full implementation - of scale subresource - it will not use it to modify the replica - count. The only thing retrieved is a label selector matching pods - grouped by the target resource. + description: |- + ScaleTargetRef points to the controller managing the set of pods for the autoscaler to + control, e.g., Deployment, StatefulSet. MultidimPodAutoscaler can be targeted at controller + implementing scale subresource (the pod set is retrieved from the controller's ScaleStatus + or some well known controllers (e.g., for DaemonSet the pod set is read from the + controller's spec). If MultidimPodAutoscaler cannot use specified target it will report + the ConfigUnsupported condition. properties: apiVersion: - description: API version of the referent + description: apiVersion is the API version of the referent type: string kind: - description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + description: 'kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: - description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + description: 'name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string required: - kind - name type: object x-kubernetes-map-type: atomic - updatePolicy: - description: Describes the rules on how changes are applied to the - pods. If not specified, all fields in the `PodUpdatePolicy` are - set to their default values. - properties: - updateMode: - description: Controls when autoscaler applies changes to the pod - resources. The default is 'Auto'. - enum: - - "Off" - - Initial - - Recreate - - Auto - type: string - type: object - constraints: - description: Describes the constraints on horizontal scaling. If not specified, all - fields in the `HorizontalScalingConstraints` are set to their default values. - properties: - minReplicas: - description: Minimal number of replicas which need to be alive - for Updater to attempt pod eviction (pending other checks like - PDB). Only positive values are allowed. Overrides global '--min-replicas' - flag. - format: int32 - type: integer - maxReplicas: - description: Maximum number of replicas which need to be alive - for Updater to attempt pod eviction (pending other checks like - PDB). Only positive values are allowed. Overrides global '--max-replicas' - flag. - format: int32 - type: integer - type: object - metrics: - description: An array of metrics describing the resource type and target. - items: - description: Each metric describes the performance or utilization goals for scaling. - properties: - type: - description: Indicates the type of the metric. - type: string - enum: - - "Object" - - "Pods" - - "Resource" - - "ContainerResource" - - "External" - object: - description: Object refers to a metric describing a single kubernetes object (e.g., hits-per-second on an Ingress object). - properties: - describedObject: - description: Specifies the descriptions of a object,such as kind,name apiVersion - properties: - kind: - description: Kind of the referent - type: string - name: - description: Name of the referent - type: string - apiVersion: - description: API version of the referent - type: string - required: - - kind - - name - type: object - target: - description: Specifies the target value for the given metric - properties: - type: - description: Represents whether the metric type is Utilization, Value, or AverageValue - type: string - enum: - - "Utilization" - - "Value" - - "AverageValue" - value: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageValue: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageUtilization: - description: 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 - required: - - type - type: object - metric: - description: Identifies the target metric by name and selector - properties: - name: - description: The name of the given metric - type: string - selector: - description: The string-encoded form of a standard Kubernetes label selector for the given metric - properties: - matchLabels: - additionalProperties: - type: string - type: object - matchExpressions: - description: A list of label selector requirements - items: - description: Label selector requirement - properties: - key: - description: The label key that the selector applies to - type: string - operator: - description: The key's relationship to a set of values. - type: string - values: - description: An array of string values. - type: array - items: - description: N/A - type: string - type: object - required: - - key - - operator - type: array - type: object - required: - - name - type: object - required: - - describedObject - - metric - - target - type: object - pods: - description: Pods refers to a metric describing each pod in the current scale target (e.g., transactions-processed-per-second). The values will be averaged together before being compared to the target value. - properties: - metric: - description: Identifies the target metric by name and selector - properties: - name: - description: The name of the given metric - type: string - selector: - description: The string-encoded form of a standard Kubernetes label selector for the given metric - properties: - matchLabels: - additionalProperties: - type: string - type: object - matchExpressions: - description: A list of label selector requirements - items: - description: Label selector requirement - properties: - key: - description: The label key that the selector applies to - type: string - operator: - description: The key's relationship to a set of values. - type: string - values: - description: An array of string values. - type: array - items: - description: N/A - type: string - type: object - required: - - key - - operator - type: array - type: object - required: - - name - type: object - target: - description: Specifies the target value for the given metric - properties: - type: - description: Represents whether the metric type is Utilization, Value, or AverageValue - type: string - enum: - - "Utilization" - - "Value" - - "AverageValue" - value: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageValue: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageUtilization: - description: 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 - required: - - type - type: object - required: - - metric - - target - type: object - resource: - 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. - properties: - name: - description: Specifies the name of the resource - type: string - target: - description: Specifies the target value for the given metric - properties: - type: - description: Represents whether the metric type is Utilization, Value, or AverageValue - type: string - enum: - - "Utilization" - - "Value" - - "AverageValue" - value: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageValue: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageUtilization: - description: 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 - required: - - type - type: object - required: - - name - - target - type: object - containerResource: - description: 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. - properties: - name: - description: Specifies the name of the resource - type: string - target: - description: Specifies the target value for the given metric - properties: - type: - description: Represents whether the metric type is Utilization, Value, or AverageValue - type: string - enum: - - "Utilization" - - "Value" - - "AverageValue" - value: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageValue: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageUtilization: - description: 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 - required: - - type - type: object - container: - description: Specifies the name of the container in the pods of the scaling target - type: string - required: - - name - - target - - container - type: object - external: - 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). - properties: - metric: - description: Identifies the target metric by name and selector - properties: - name: - description: The name of the given metric - type: string - selector: - description: The string-encoded form of a standard Kubernetes label selector for the given metric - properties: - matchLabels: - additionalProperties: - type: string - type: object - matchExpressions: - description: A list of label selector requirements - items: - description: Label selector requirement - properties: - key: - description: The label key that the selector applies to - type: string - operator: - description: The key's relationship to a set of values. - type: string - values: - description: An array of string values. - type: array - items: - description: N/A - type: string - type: object - required: - - key - - operator - type: array - type: object - required: - - name - type: object - target: - description: Specifies the target value for the given metric - properties: - type: - description: Represents whether the metric type is Utilization, Value, or AverageValue - type: string - enum: - - "Utilization" - - "Value" - - "AverageValue" - value: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageValue: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageUtilization: - description: 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 - required: - - type - type: object - required: - - metric - - target - type: object - required: - - type - type: object - type: array required: - scaleTargetRef type: object @@ -756,9 +863,9 @@ spec: description: Current information about the autoscaler. properties: conditions: - description: Conditions is the set of conditions required for this - autoscaler to scale its target, and indicates whether or not those - conditions are met. + description: |- + Conditions is the set of conditions required for this autoscaler to scale its target, and + indicates whether or not those conditions are met. items: description: MultidimPodAutoscalerCondition describes the state of a MultidimPodAutoscaler at a certain point. @@ -787,382 +894,518 @@ spec: - type type: object type: array - recommendation: - description: The most recently computed amount of resources recommended - by the autoscaler for the controlled pods. - properties: - containerRecommendations: - description: Resources recommended by the autoscaler for each - container. - items: - description: RecommendedContainerResources is the recommendation - of resources computed by autoscaler for a specific container. - Respects the container resource policy if present in the spec. - In particular the recommendation is not produced for containers - with `ContainerScalingMode` set to 'Off'. + currentMetrics: + description: The last read state of the metrics used by this autoscaler. + items: + description: MetricStatus describes the last-read state of a single + metric. + properties: + containerResource: + 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. properties: - containerName: - description: Name of the container. + container: + description: container is the name of the container in the + pods of the scaling target type: string - lowerBound: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: Minimum recommended amount of resources. Observes - ContainerResourcePolicy. This amount is not guaranteed - to be sufficient for the application to operate in a stable - way, however running with less resources is likely to - have significant impact on performance/availability. - type: object - target: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: Recommended amount of resources. Observes ContainerResourcePolicy. - type: object - uncappedTarget: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: The most recent recommended resources target - computed by the autoscaler for the controlled pods, based - only on actual resource usage, not taking into account - the ContainerResourcePolicy. May differ from the Recommendation - if the actual resource usage causes the target to violate - the ContainerResourcePolicy (lower than MinAllowed or - higher that MaxAllowed). Used only as status indication, - will not affect actual resource assignment. - type: object - upperBound: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: Maximum recommended amount of resources. Observes - ContainerResourcePolicy. Any resources allocated beyond - this value are likely wasted. This value may be larger - than the maximum amount of application is actually capable - of consuming. + current: + description: current contains the current value for the + given metric + properties: + averageUtilization: + 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. + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + description: |- + averageValue is the current value of the average of the + metric across all relevant pods (as a quantity) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + value: + anyOf: + - type: integer + - type: string + description: value is the current value of the metric + (as a quantity). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object + name: + description: name is the name of the resource in question. + type: string required: - - target + - container + - current + - name type: object - type: array - type: object - lastScaleTime: - description: The last time the MultidimPodAutoscaler scaled. - format: date-time - type: string - currentReplicas: - description: The current number of replicas - format: int32 - type: integer - desiredReplicas: - description: The desired number of replicas - format: int32 - type: integer - currentMetrics: - description: The last read state of the metrics used by this autoscaler. - items: - description: Describes the last-read state of a single metric. - properties: - type: - description: The type of metric source. - type: string - object: - description: A metric describing a single Kubernetes object. + external: + 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). properties: + current: + description: current contains the current value for the + given metric + properties: + averageUtilization: + 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. + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + description: |- + averageValue is the current value of the average of the + metric across all relevant pods (as a quantity) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + value: + anyOf: + - type: integer + - type: string + description: value is the current value of the metric + (as a quantity). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object metric: - description: Identifies the target metric by name and selector + description: metric identifies the target metric by name + and selector properties: name: - description: The name of the given metric + description: name is the name of the given metric type: string selector: - description: The string-encoded form of a standard Kubernetes label selector for the given metric + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. + When unset, just the metricName will be used to gather metrics. properties: - matchLabels: - additionalProperties: - type: string - type: object matchExpressions: - description: A list of label selector requirements + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. items: - description: Label selector requirement + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: - description: The label key that the selector applies to + description: key is the label key that the + selector applies to. type: string operator: - description: The key's relationship to a set of values. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: An array of string values. - type: array + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: - description: N/A type: string - type: object + type: array + x-kubernetes-list-type: atomic required: - key - operator + type: object type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object type: object + x-kubernetes-map-type: atomic required: - name type: object + required: + - current + - metric + type: object + object: + description: |- + object refers to a metric describing a single kubernetes object + (for example, hits-per-second on an Ingress object). + properties: current: - description: The current value for the given metric. + description: current contains the current value for the + given metric properties: - value: + averageUtilization: + 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. + format: int32 + type: integer + averageValue: anyOf: - type: integer - type: string + description: |- + averageValue is the current value of the average of the + metric across all relevant pods (as a quantity) pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - averageValue: + value: anyOf: - type: integer - type: string + description: value is the current value of the metric + (as a quantity). pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - averageUtilization: - description: 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 type: object describedObject: - description: Specifies the descriptions of a object,such as kind,name apiVersion + description: DescribedObject specifies the descriptions + of a object,such as kind,name apiVersion properties: + apiVersion: + description: apiVersion is the API version of the referent + type: string kind: - description: Kind of the referent + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: - description: Name of the referent - type: string - apiVersion: - description: API version of the referent + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string required: - kind - name type: object - required: - - current - - metric - - describedObject - type: object - pods: - description: A metric describing each pod in the current scale target. - properties: metric: - description: Identifies the target metric by name and selector + description: metric identifies the target metric by name + and selector properties: name: - description: The name of the given metric + description: name is the name of the given metric type: string selector: - description: The string-encoded form of a standard Kubernetes label selector for the given metric + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. + When unset, just the metricName will be used to gather metrics. properties: - matchLabels: - additionalProperties: - type: string - type: object matchExpressions: - description: A list of label selector requirements + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. items: - description: Label selector requirement + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: - description: The label key that the selector applies to + description: key is the label key that the + selector applies to. type: string operator: - description: The key's relationship to a set of values. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: An array of string values. - type: array + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: - description: N/A type: string - type: object + type: array + x-kubernetes-list-type: atomic required: - key - operator + type: object type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object type: object + x-kubernetes-map-type: atomic required: - name type: object - current: - description: The current value for the given metric. - properties: - value: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageValue: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageUtilization: - description: 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 - type: object required: - current + - describedObject - metric type: object - resource: - description: A resource metric (request or limit) known to Kubernetes describing each pod in the scale target. + pods: + description: |- + 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. properties: - name: - description: The name of the resource. - type: string current: - description: The current value for the given metric. + description: current contains the current value for the + given metric properties: - value: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - averageValue: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true averageUtilization: - description: 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 + 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. format: int32 type: integer - type: object - required: - - current - - name - type: object - containerResource: - description: A resource metric (request or limit) known to Kubernetes describing a single container in the scale target. - properties: - name: - description: The name of the resource. - type: string - current: - description: The current value for the given metric. - properties: - value: + averageValue: anyOf: - type: integer - type: string + description: |- + averageValue is the current value of the average of the + metric across all relevant pods (as a quantity) pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - averageValue: + value: anyOf: - type: integer - type: string + description: value is the current value of the metric + (as a quantity). pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - averageUtilization: - description: 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 type: object - container: - description: The name of the container in the pods of the scaling target. - type: string - required: - - current - - name - - container - type: object - external: - description: A global metric that is not associated with any Kubernetes object. - properties: metric: - description: Identifies the target metric by name and selector + description: metric identifies the target metric by name + and selector properties: name: - description: The name of the given metric + description: name is the name of the given metric type: string selector: - description: The string-encoded form of a standard Kubernetes label selector for the given metric + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. + When unset, just the metricName will be used to gather metrics. properties: - matchLabels: - additionalProperties: - type: string - type: object matchExpressions: - description: A list of label selector requirements + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. items: - description: Label selector requirement + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: - description: The label key that the selector applies to + description: key is the label key that the + selector applies to. type: string operator: - description: The key's relationship to a set of values. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: An array of string values. - type: array + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: - description: N/A type: string - type: object + type: array + x-kubernetes-list-type: atomic required: - key - operator + type: object type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object type: object + x-kubernetes-map-type: atomic required: - name type: object + required: + - current + - metric + type: object + resource: + 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. + properties: current: - description: The current value for the given metric. + description: current contains the current value for the + given metric properties: - value: + averageUtilization: + 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. + format: int32 + type: integer + averageValue: anyOf: - type: integer - type: string + description: |- + averageValue is the current value of the average of the + metric across all relevant pods (as a quantity) pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - averageValue: + value: anyOf: - type: integer - type: string + description: value is the current value of the metric + (as a quantity). pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - averageUtilization: - description: 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 type: object + name: + description: name is the name of the resource in question. + type: string required: - - metric - current + - name type: object - type: object + type: + 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 required: - type + type: object type: array + x-kubernetes-list-type: atomic + currentReplicas: + description: Current number of replicas of pods managed by this autoscaler. + format: int32 + type: integer + desiredReplicas: + description: Desired number of replicas of pods managed by this autoscaler. + format: int32 + type: integer + lastScaleTime: + description: |- + Last time the MultidimPodAutoscaler scaled the number of pods and resizes containers; + Used by the autoscaler to control how often scaling operations are performed. + format: date-time + type: string + recommendation: + description: |- + The most recently computed amount of resources for each controlled pod recommended by the + autoscaler. + properties: + containerRecommendations: + description: Resources recommended by the autoscaler for each + container. + items: + description: |- + RecommendedContainerResources is the recommendation of resources computed by + autoscaler for a specific container. Respects the container resource policy + if present in the spec. In particular the recommendation is not produced for + containers with `ContainerScalingMode` set to 'Off'. + properties: + containerName: + description: Name of the container. + type: string + lowerBound: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Minimum recommended amount of resources. Observes ContainerResourcePolicy. + This amount is not guaranteed to be sufficient for the application to operate in a stable way, however + running with less resources is likely to have significant impact on performance/availability. + type: object + target: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Recommended amount of resources. Observes ContainerResourcePolicy. + type: object + uncappedTarget: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + The most recent recommended resources target computed by the autoscaler + for the controlled pods, based only on actual resource usage, not taking + into account the ContainerResourcePolicy. + May differ from the Recommendation if the actual resource usage causes + the target to violate the ContainerResourcePolicy (lower than MinAllowed + or higher that MaxAllowed). + Used only as status indication, will not affect actual resource assignment. + type: object + upperBound: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Maximum recommended amount of resources. Observes ContainerResourcePolicy. + Any resources allocated beyond this value are likely wasted. This value may be larger than the maximum + amount of application is actually capable of consuming. + type: object + required: + - target + type: object + type: array + type: object required: - currentReplicas - desiredReplicas diff --git a/multidimensional-pod-autoscaler/deploy/mpa-v1alpha1-crd.yaml b/multidimensional-pod-autoscaler/deploy/mpa-v1alpha1-crd.yaml deleted file mode 100644 index 363ccb54735a..000000000000 --- a/multidimensional-pod-autoscaler/deploy/mpa-v1alpha1-crd.yaml +++ /dev/null @@ -1,117 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: multidimpodautoscalers.autoscaling.k8s.io - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes/kubernetes/pull/63797 - controller-gen.kubebuilder.io/version: v0.9.2 -spec: - group: autoscaling.k8s.io - scope: Namespaced - names: - plural: multidimpodautoscalers - singular: multidimpodautoscalers - kind: MultidimPodAutoscaler - shortNames: - - mpa - version: v1alpha1 - versions: - - name: v1alpha1 - served: false - storage: false - validation: - # openAPIV3Schema is the schema for validating custom objects. - openAPIV3Schema: - type: object - properties: - spec: - type: object - required: [] - properties: - scaleTargetRef: - type: object - updatePolicy: - type: object - properties: - updateMode: - type: string - goals: - type: object - properties: - goalMetrics: - type: array - items: - type: object - properties: - type: - type: string - enum: ["CPUUtilization", "MemoryUtilization", "Latency", "Throughput"] - avgTarget: - type: float - constraints: - type: object - properties: - minReplicas: - type: integer - maxReplicas: - type: integer - resourcePolicy: - type: object - properties: - containerPolicies: - type: array - items: - type: object - properties: - containerName: - type: string - controlledValues: - type: string - enum: ["RequestsAndLimits", "RequestsOnly"] - mode: - type: string - enum: ["Auto", "Off"] - minAllowed: - type: object - maxAllowed: - type: object - controlledResources: - type: array - items: - type: string - enum: ["ResourceCPU", "ResourceMemory"] - recommenders: - type: array - items: - type: object - properties: - name: - type: string ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: verticalpodautoscalercheckpoints.autoscaling.k8s.io - annotations: - "api-approved.kubernetes.io": "https://github.com/kubernetes/kubernetes/pull/63797" -spec: - group: autoscaling.k8s.io - scope: Namespaced - names: - plural: verticalpodautoscalercheckpoints - singular: verticalpodautoscalercheckpoint - kind: VerticalPodAutoscalerCheckpoint - shortNames: - - vpacheckpoint - version: v1beta1 - versions: - - name: v1beta1 - served: false - storage: false - - name: v1beta2 - served: true - storage: true - - name: v1 - served: true - storage: false diff --git a/multidimensional-pod-autoscaler/hack/boilerplate.go.txt b/multidimensional-pod-autoscaler/hack/boilerplate.go.txt new file mode 100644 index 000000000000..0926592d3895 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 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. +*/ diff --git a/multidimensional-pod-autoscaler/hack/deploy-for-e2e-locally.sh b/multidimensional-pod-autoscaler/hack/deploy-for-e2e-locally.sh new file mode 100755 index 000000000000..391c24ae1ae1 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/deploy-for-e2e-locally.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Copyright 2023 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. + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. + +function print_help { + echo "ERROR! Usage: deploy-for-e2e-locally.sh [suite]*" + echo " should be one of:" + echo " - recommender" + echo " - recommender-externalmetrics" +} + +if [ $# -eq 0 ]; then + print_help + exit 1 +fi + +if [ $# -gt 1 ]; then + print_help + exit 1 +fi + +SUITE=$1 + +case ${SUITE} in + recommender|recommender-externalmetrics) + COMPONENTS="${SUITE}" + ;; + *) + print_help + exit 1 + ;; +esac + +# Local KIND-hosted registry +export REGISTRY=${REGISTRY:-localhost:5001} +export TAG=${TAG:-latest} + +rm -f ${SCRIPT_ROOT}/hack/e2e/mpa-rbac.yaml +patch -c ${SCRIPT_ROOT}/deploy/mpa-rbac.yaml -i ${SCRIPT_ROOT}/hack/e2e/mpa-rbac.diff -o ${SCRIPT_ROOT}/hack/e2e/mpa-rbac.yaml +kubectl apply -f ${SCRIPT_ROOT}/hack/e2e/mpa-rbac.yaml +# Other-versioned CRDs are irrelevant as we're running a modern-ish cluster. +kubectl apply -f ${SCRIPT_ROOT}/deploy/mpa-v1alpha1-crd-gen.yaml +kubectl apply -f ${SCRIPT_ROOT}/hack/e2e/k8s-metrics-server.yaml + +for i in ${COMPONENTS}; do + if [ $i == recommender-externalmetrics ] ; then + i=recommender + fi + ALL_ARCHITECTURES=amd64 make --directory ${SCRIPT_ROOT}/pkg/${i} release REGISTRY=${REGISTRY} TAG=${TAG} + kind load docker-image ${REGISTRY}/vpa-${i}-amd64:${TAG} +done + + +for i in ${COMPONENTS}; do + if [ $i == recommender-externalmetrics ] ; then + kubectl delete namespace monitoring --ignore-not-found=true + kubectl create namespace monitoring + kubectl apply -f ${SCRIPT_ROOT}/hack/e2e/prometheus.yaml + kubectl apply -f ${SCRIPT_ROOT}/hack/e2e/prometheus-adapter.yaml + kubectl apply -f ${SCRIPT_ROOT}/hack/e2e/metrics-pump.yaml + kubectl apply -f ${SCRIPT_ROOT}/hack/e2e/${i}-deployment.yaml + else + REGISTRY=${REGISTRY} TAG=${TAG} ${SCRIPT_ROOT}/hack/vpa-process-yaml.sh ${SCRIPT_ROOT}/deploy/${i}-deployment.yaml | kubectl apply -f - + fi +done diff --git a/multidimensional-pod-autoscaler/hack/deploy-for-e2e.sh b/multidimensional-pod-autoscaler/hack/deploy-for-e2e.sh new file mode 100755 index 000000000000..695c032072fc --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/deploy-for-e2e.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +# Copyright 2018 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. + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. + +function print_help { + echo "ERROR! Usage: deploy-for-e2e.sh [suite]*" + echo " should be one of:" + echo " - recommender" + echo " - updater" + echo " - admission-controller" + echo " - actuation" + echo " - full-vpa" + echo "If component is not specified all above will be started." +} + +if [ $# -eq 0 ]; then + print_help + exit 1 +fi + +if [ $# -gt 1 ]; then + print_help + exit 1 +fi + +SUITE=$1 + +case ${SUITE} in + recommender|updater|admission-controller) + COMPONENTS="${SUITE}" + ;; + full-vpa) + COMPONENTS="recommender updater admission-controller" + ;; + actuation) + COMPONENTS="updater admission-controller" + ;; + *) + print_help + exit 1 + ;; +esac + +export REGISTRY=gcr.io/`gcloud config get-value core/project` +export TAG=latest + +echo "Configuring registry authentication" +mkdir -p "${HOME}/.docker" +gcloud auth configure-docker -q + +for i in ${COMPONENTS}; do + if [ $i == admission-controller ] ; then + (cd ${SCRIPT_ROOT}/pkg/${i} && bash ./gencerts.sh e2e || true) + fi + ALL_ARCHITECTURES=amd64 make --directory ${SCRIPT_ROOT}/pkg/${i} release +done + +kubectl create -f ${SCRIPT_ROOT}/deploy/mpa-v1alpha1-crd-gen.yaml +kubectl create -f ${SCRIPT_ROOT}/deploy/mpa-rbac.yaml + +for i in ${COMPONENTS}; do + ${SCRIPT_ROOT}/hack/vpa-process-yaml.sh ${SCRIPT_ROOT}/deploy/${i}-deployment.yaml | kubectl create -f - +done diff --git a/multidimensional-pod-autoscaler/hack/e2e/Dockerfile.externalmetrics-writer b/multidimensional-pod-autoscaler/hack/e2e/Dockerfile.externalmetrics-writer new file mode 100644 index 000000000000..5af909d2c459 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/e2e/Dockerfile.externalmetrics-writer @@ -0,0 +1,18 @@ +# Copyright 2023 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. + +FROM python:3.10-slim +RUN pip3 install kubernetes argparse requests + +COPY emit-metrics.py / diff --git a/multidimensional-pod-autoscaler/hack/e2e/k8s-metrics-server.yaml b/multidimensional-pod-autoscaler/hack/e2e/k8s-metrics-server.yaml new file mode 100644 index 000000000000..25984da14287 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/e2e/k8s-metrics-server.yaml @@ -0,0 +1,244 @@ +--- +# Source: metrics-server/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: local-metrics-server + namespace: default + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm +--- +# Source: metrics-server/templates/clusterrole-aggregated-reader.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: system:metrics-server-aggregated-reader + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-view: "true" +rules: + - apiGroups: + - metrics.k8s.io + resources: + - pods + - nodes + verbs: + - get + - list + - watch +--- +# Source: metrics-server/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: system:local-metrics-server + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm +rules: + - apiGroups: + - "" + resources: + - nodes/metrics + verbs: + - get + - apiGroups: + - "" + resources: + - pods + - nodes + - namespaces + - configmaps + verbs: + - get + - list + - watch +--- +# Source: metrics-server/templates/clusterrolebinding-auth-delegator.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: local-metrics-server:system:auth-delegator + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: + - kind: ServiceAccount + name: local-metrics-server + namespace: default +--- +# Source: metrics-server/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: system:local-metrics-server + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:local-metrics-server +subjects: + - kind: ServiceAccount + name: local-metrics-server + namespace: default +--- +# Source: metrics-server/templates/rolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: local-metrics-server-auth-reader + namespace: default + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: + - kind: ServiceAccount + name: local-metrics-server + namespace: default +--- +# Source: metrics-server/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: local-metrics-server + namespace: default + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + ports: + - name: https + port: 443 + protocol: TCP + targetPort: https + selector: + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server +--- +# Source: metrics-server/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: local-metrics-server + namespace: default + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + template: + metadata: + labels: + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + spec: + schedulerName: + serviceAccountName: local-metrics-server + priorityClassName: "system-cluster-critical" + containers: + - name: metrics-server + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + image: registry.k8s.io/metrics-server/metrics-server:v0.6.2 + imagePullPolicy: IfNotPresent + args: + - --secure-port=10250 + - --cert-dir=/tmp + - --kubelet-insecure-tls + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + ports: + - name: https + protocol: TCP + containerPort: 10250 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /livez + port: https + scheme: HTTPS + initialDelaySeconds: 0 + periodSeconds: 10 + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: https + scheme: HTTPS + initialDelaySeconds: 20 + periodSeconds: 10 + volumeMounts: + - name: tmp + mountPath: /tmp + volumes: + - name: tmp + emptyDir: {} +--- +# Source: metrics-server/templates/apiservice.yaml +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: v1beta1.metrics.k8s.io + labels: + helm.sh/chart: metrics-server-3.8.3 + app.kubernetes.io/name: metrics-server + app.kubernetes.io/instance: local-metrics-server + app.kubernetes.io/version: "0.6.2" + app.kubernetes.io/managed-by: Helm +spec: + group: metrics.k8s.io + groupPriorityMinimum: 100 + insecureSkipTLSVerify: true + service: + name: local-metrics-server + namespace: default + port: 443 + version: v1beta1 + versionPriority: 100 diff --git a/multidimensional-pod-autoscaler/hack/e2e/kind-with-registry.sh b/multidimensional-pod-autoscaler/hack/e2e/kind-with-registry.sh new file mode 100755 index 000000000000..8dba9f3d9ff4 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/e2e/kind-with-registry.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# Copyright 2023 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. + +# Based on https://kind.sigs.k8s.io/examples/kind-with-registry.sh +set -o errexit + +# Create registry container unless it already exists +reg_name='kind-registry' +reg_port='5001' + +if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then + docker run \ + -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \ + registry:2 +fi + +# Create a cluster with the local registry enabled in containerd +cat <>{<<.LabelMatchers>>}) by (name) + resources: + overrides: + kubernetes_namespace: { resource: namespace } + kubernetes_pod_name: { resource: pod } + - seriesQuery: '{__name__="mem"}' + metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (name) + resources: + overrides: + kubernetes_namespace: { resource: namespace } + kubernetes_pod_name: { resource: pod } + rules: + - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' + seriesFilters: [] + resources: + overrides: + namespace: + resource: namespace + pod: + resource: pod + name: + matches: ^container_(.*)_seconds_total$ + as: "" + metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[5m])) + by (<<.GroupBy>>) + - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' + seriesFilters: + - isNot: ^container_.*_seconds_total$ + resources: + overrides: + namespace: + resource: namespace + pod: + resource: pod + name: + matches: ^container_(.*)_total$ + as: "" + metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[5m])) + by (<<.GroupBy>>) + - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' + seriesFilters: + - isNot: ^container_.*_total$ + resources: + overrides: + namespace: + resource: namespace + pod: + resource: pod + name: + matches: ^container_(.*)$ + as: "" + metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>,container!="POD"}) by (<<.GroupBy>>) + - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' + seriesFilters: + - isNot: .*_total$ + resources: + template: <<.Resource>> + name: + matches: "" + as: "" + metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) + - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' + seriesFilters: + - isNot: .*_seconds_total + resources: + template: <<.Resource>> + name: + matches: ^(.*)_total$ + as: "" + metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>) + - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' + seriesFilters: [] + resources: + template: <<.Resource>> + name: + matches: ^(.*)_seconds_total$ + as: "" + metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>) +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/instance: prometheus-adapter + app.kubernetes.io/name: prometheus-adapter + name: prometheus-adapter + namespace: monitoring +spec: + progressDeadlineSeconds: 600 + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: prometheus-adapter + app.kubernetes.io/name: prometheus-adapter + template: + metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/instance: prometheus-adapter + app.kubernetes.io/name: prometheus-adapter + name: prometheus-adapter + spec: + containers: + - name: prometheus-adapter + args: + - /adapter + - --secure-port=6443 + - --cert-dir=/tmp/cert + - --logtostderr=true + - --prometheus-url=http://prometheus.monitoring.svc:9090 + - --metrics-relist-interval=1m + - --v=4 + - --config=/etc/adapter/config.yaml + image: registry.k8s.io/prometheus-adapter/prometheus-adapter:v0.10.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: https + scheme: HTTPS + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - containerPort: 6443 + name: https + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: https + scheme: HTTPS + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - all + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 10001 + seccompProfile: + type: RuntimeDefault + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/adapter/ + name: config + readOnly: true + - mountPath: /tmp + name: tmp + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccount: prometheus-adapter + serviceAccountName: prometheus-adapter + terminationGracePeriodSeconds: 30 + volumes: + - configMap: + defaultMode: 420 + name: prometheus-adapter + name: config + - emptyDir: {} + name: tmp diff --git a/multidimensional-pod-autoscaler/hack/e2e/prometheus.yaml b/multidimensional-pod-autoscaler/hack/e2e/prometheus.yaml new file mode 100644 index 000000000000..651cf81ab256 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/e2e/prometheus.yaml @@ -0,0 +1,264 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-server-conf + labels: + name: prometheus-server-conf + namespace: monitoring +data: + prometheus.rules: |- + groups: + - name: devopscube demo alert + rules: + - alert: High Pod Memory + expr: sum(container_memory_usage_bytes) > 1 + for: 1m + labels: + severity: slack + annotations: + summary: High Memory Usage + prometheus.yml: |- + global: + scrape_interval: 5s + evaluation_interval: 5s + rule_files: + - /etc/prometheus/prometheus.rules + + scrape_configs: + - job_name: 'kubernetes-apiservers' + + kubernetes_sd_configs: + - role: endpoints + scheme: https + + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + relabel_configs: + - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] + action: keep + regex: default;kubernetes;https + + - job_name: 'kubernetes-pods' + + kubernetes_sd_configs: + - role: pod + + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] + action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: kubernetes_pod_name + + - job_name: 'kubernetes-service-endpoints' + + kubernetes_sd_configs: + - role: endpoints + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: replace + target_label: __scheme__ + regex: (https?) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_service_name] + action: replace + target_label: kubernetes_name + + - job_name: "pushgateway" + honor_labels: true + static_configs: + - targets: ['localhost:9091'] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: prometheus +rules: +- apiGroups: [""] + resources: + - nodes + - nodes/proxy + - services + - endpoints + - pods + - configmaps + verbs: ["get", "list", "watch"] +- apiGroups: + - extensions + resources: + - ingresses + verbs: ["get", "list", "watch"] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: ["create"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: prometheus +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prometheus +subjects: +- kind: ServiceAccount + name: prometheus + namespace: monitoring +- kind: ServiceAccount + name: metrics-pump + namespace: monitoring +- kind: ServiceAccount + name: prometheus-adapter + namespace: monitoring + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: prometheus + namespace: monitoring +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: metrics-pump + namespace: monitoring +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: prometheus-adapter + namespace: monitoring + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: prometheus + namespace: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app: prometheus + template: + metadata: + labels: + app: prometheus + spec: + serviceAccountName: prometheus + securityContext: + runAsNonRoot: true + runAsUser: 65534 # nobody + containers: + - name: prometheus + image: prom/prometheus + args: + - "--storage.tsdb.retention.time=12h" + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus/" + ports: + - containerPort: 9090 + name: prometheus + resources: + requests: + cpu: 500m + memory: 500M + limits: + cpu: 1 + memory: 1Gi + volumeMounts: + - name: prometheus-config-volume + mountPath: /etc/prometheus/ + - name: prometheus-storage-volume + mountPath: /prometheus/ + - name: pushgateway + image: prom/pushgateway + ports: + - containerPort: 9091 + name: pushgateway + resources: + requests: + cpu: 500m + memory: 500M + volumes: + - name: prometheus-config-volume + configMap: + defaultMode: 420 + name: prometheus-server-conf + - name: prometheus-storage-volume + emptyDir: {} + +--- +apiVersion: v1 +kind: Service +metadata: + name: prometheus + namespace: monitoring +spec: + selector: + app: prometheus + ports: + - name: prometheus + protocol: TCP + port: 9090 + targetPort: prometheus + - name: pushgateway + protocol: TCP + port: 9091 + targetPort: pushgateway +--- +apiVersion: v1 +kind: Service +metadata: + name: prometheus-adapter + namespace: monitoring +spec: + selector: + app.kubernetes.io/name: prometheus-adapter + ports: + - name: api + protocol: TCP + port: 443 + targetPort: https + diff --git a/multidimensional-pod-autoscaler/hack/e2e/recommender-externalmetrics-deployment.yaml b/multidimensional-pod-autoscaler/hack/e2e/recommender-externalmetrics-deployment.yaml new file mode 100644 index 000000000000..bf033a8294ce --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/e2e/recommender-externalmetrics-deployment.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vpa-recommender + namespace: kube-system +spec: + replicas: 1 + selector: + matchLabels: + app: vpa-recommender + template: + metadata: + labels: + app: vpa-recommender + spec: + serviceAccountName: vpa-recommender + securityContext: + runAsNonRoot: true + runAsUser: 65534 # nobody + containers: + - name: recommender + image: localhost:5001/vpa-recommender-amd64:latest + imagePullPolicy: Never + args: + - /recommender-amd64 + - --use-external-metrics=true + - --external-metrics-cpu-metric=cpu + - --external-metrics-memory-metric=mem + - --v=4 + resources: + limits: + cpu: 200m + memory: 1000Mi + requests: + cpu: 50m + memory: 500Mi + ports: + - name: prometheus + containerPort: 8942 + - name: delve + containerPort: 40000 diff --git a/multidimensional-pod-autoscaler/hack/emit-metrics.py b/multidimensional-pod-autoscaler/hack/emit-metrics.py new file mode 100755 index 000000000000..c568536f566f --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/emit-metrics.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 + +# Copyright 2023 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. + +# This script runs as a pod, scanning the cluster for other pods. +# It then publishes fake metrics (Gaussian by --mean_* and --stddev_*) +# for each pod into a Prometheus Pushgateway. The Prometheus instance +# connected to that Pushgateway can have a Prometheus Adapter connected +# to it that serves as an External Metrics Provider to Kubernetes. + +import argparse +import base64 +from collections import defaultdict +from kubernetes import client, config +import math +import random +import re +import requests +import sys +import time +import urllib.parse +import pprint + +def parse_arguments(): + parser = argparse.ArgumentParser(description='') + parser.add_argument('--dest', type=str, default='pushservice') + parser.add_argument('--mean_cpu', type=int, default='1000', help='Mean millicores for cpu.') + parser.add_argument('--mean_mem', type=int, default='128', help='Mean megabytes for memory.') + parser.add_argument('--stddev_cpu', type=int, default=150, help='Standard deviation for cpu.') + parser.add_argument('--stddev_mem', type=int, default=15, help='Standard deviation for mem.') + parser.add_argument('--sleep_sec', type=int, default=30, help='Delay between metric-sends, in seconds.') + parser.add_argument('-t','--tags', action='append', nargs=2, metavar=('key','value'), default=[['data', 'emit-metrics']], + help='Additional tags to attach to metrics.') + parser.add_argument('--namespace_pattern', default='monitoring', help='Regex to match namespace names.') + parser.add_argument('--pod_pattern', default='prometheus-[0-9a-f]{9}-[0-9a-z]{5}', help='Regex to match pod names.') + parser.add_argument('--all', default=False, action='store_true', help='Write metrics for all pods.') + parser.add_argument('--job', default='emit-metrics', help='Job name to submit under.') + return parser.parse_args() + +def safestr(s): + '''Is s a URL-safe string?''' + return s.strip('_').isalnum() + +def urlify(key, value): + replacements = { ".": "%2E", "-": "%2D" } + def encode(s): + s = urllib.parse.quote(s, safe='') + for c,repl in replacements.items(): + s = s.replace(c, repl) + return s + if safestr(key) and safestr(value): + return f"{key}/{value}" + elif len(value) == 0: + # Possibly encode the key using URI encoding, but + # definitely use base64 for the value. + return encode(key)+"@base64/=" + else: + return f"{encode(key)}/{encode(value)}" + +def valid_key(key): + invalid_char_re = re.compile(r'.*[./-].*') + invalid_keys = set(["pod-template-hash", "k8s-app", "controller-uid", + "controller-revision-hash", "pod-template-generation"]) + return (key not in invalid_keys) and invalid_char_re.match(key) == None + +def send_metrics(args, job, path, cpuval, memval): + cpuval = cpuval / 1000.0 # Scale from millicores to cores + payload = f"cpu {cpuval:.3f}\nmem {memval:d}.0\n" + path_str = '/'.join([urlify(key,value) for key, value in path.items()]) + url = f'http://{args.dest}/metrics/job/{job}/namespace/{path["namespace"]}/{path_str}' + response = requests.put(url=url, data=bytes(payload, 'utf-8')) + if response.status_code != 200: + print (f"Writing to {url}.\n>> Got {response.status_code}: {response.reason}, {response.text}\n>> Dict was:") + pprint.pprint(path) + else: + print (f"Wrote to {url}: {payload}") + sys.stdout.flush() + +def main(args): + print (f"Starting up.") + sys.stdout.flush() + pod_name_pattern = re.compile(args.pod_pattern) + namespace_name_pattern = re.compile(args.namespace_pattern) + try: + config.load_kube_config() + except: + config.load_incluster_config() + v1 = client.CoreV1Api() + print (f"Initialized. Sleep interval is for {args.sleep_sec} seconds.") + sys.stdout.flush() + pod_cache = dict() + while True: + skipped_keys= set() + time.sleep(args.sleep_sec) + pods = v1.list_pod_for_all_namespaces(watch=False) + all = 0 + found = 0 + for pod in pods.items: + all += 1 + job = args.job + if args.all or (namespace_name_pattern.match(pod.metadata.namespace) and pod_name_pattern.match(pod.metadata.name)): + # Get container names and send metrics for each. + key = f"{pod.metadata.namespace}/{pod.metadata.name}" + if key not in pod_cache: + v1pod = v1.read_namespaced_pod(pod.metadata.name, pod.metadata.namespace, pretty=False) + pod_cache[key] = v1pod + else: + v1pod = pod_cache[key] + containers = [ c.name for c in v1pod.spec.containers ] + found += 1 + path = { "kubernetes_namespace": pod.metadata.namespace, + "kubernetes_pod_name": pod.metadata.name, + "pod": pod.metadata.name, + "namespace": pod.metadata.namespace} + # Append metadata to the data point, add the labels second to overwrite annotations on + # conflict + try: + if v1pod.metadata.annotations: + for k,v in v1pod.metadata.annotations.items(): + if valid_key(k): + path[k] = v + else: + skipped_keys |= set([k]) + if v1pod.metadata.labels: + for k,v in v1pod.metadata.labels.items(): + if valid_key(k): + path[k] = v + else: + skipped_keys |= set([k]) + except ValueError as err: + print (f"{err} on {v1pod.metadata} when getting annotations/labels") + if "job" in path: + job = path["job"] + for container in containers: + cpuval = random.normalvariate(args.mean_cpu, args.stddev_cpu) + memval = random.normalvariate(args.mean_mem, args.stddev_mem) + path['name'] = container + path['container'] = container + send_metrics(args, job, path, math.floor(cpuval), math.floor(memval * 1048576.0)) + print(f"Found {found} out of {all} pods. Skipped keys:") + pprint.pprint(skipped_keys) + +if __name__ == '__main__': + main(parse_arguments()) diff --git a/multidimensional-pod-autoscaler/hack/generate-crd-yaml.sh b/multidimensional-pod-autoscaler/hack/generate-crd-yaml.sh new file mode 100755 index 000000000000..9931a913fb50 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/generate-crd-yaml.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# Copyright 2020 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. + +set -o errexit +set -o nounset +set -o pipefail + +REPOSITORY_ROOT=$(realpath $(dirname ${BASH_SOURCE})/..) +CRD_OPTS=crd:allowDangerousTypes=true +APIS_PATH=${REPOSITORY_ROOT}/pkg/apis +OUTPUT=${REPOSITORY_ROOT}/deploy/mpa-v1alpha1-crd-gen.yaml +WORKSPACE=$(mktemp -d) + +function cleanup() { + rm -r ${WORKSPACE} +} +trap cleanup EXIT + +if [[ -z $(which controller-gen) ]]; then + ( + cd $WORKSPACE + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.9.2 + ) + CONTROLLER_GEN=${GOBIN:-$(go env GOPATH)/bin}/controller-gen +else + CONTROLLER_GEN=$(which controller-gen) +fi + +# The following commands always returns an error because controller-gen does not accept keys other than strings. +${CONTROLLER_GEN} ${CRD_OPTS} paths="${APIS_PATH}/..." output:crd:dir="\"${WORKSPACE}\"" >& ${WORKSPACE}/errors.log ||: +grep -v -e 'map keys must be strings, not int' -e 'not all generators ran successfully' -e 'usage' ${WORKSPACE}/errors.log \ + && { echo "Failed to generate CRD YAMLs."; exit 1; } + +cd ${WORKSPACE} +cat < kustomization.yaml +resources: +- autoscaling.k8s.io_multidimpodautoscalers.yaml +commonAnnotations: + "api-approved.kubernetes.io": "https://github.com/kubernetes/kubernetes/pull/63797" +EOF +echo --- > ${OUTPUT} +kubectl kustomize . >> ${OUTPUT} diff --git a/multidimensional-pod-autoscaler/hack/local-cluster.md b/multidimensional-pod-autoscaler/hack/local-cluster.md new file mode 100644 index 000000000000..39be865fed24 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/local-cluster.md @@ -0,0 +1,31 @@ +# Running Integration Tests locally +Included in parallel with `run-e2e.sh` and `deploy-for-e2e.sh` are two alternate versions +with `-locally` as part of their names. They use Kubernetes in Docker (`kind`) to run a local +cluster in Docker. Using them will require `docker` and `kind` in your `PATH`. + +## External Metrics Tests +The external metrics tests (`recommender-externalmetrics`, available on the `-locally` variants) +use a stack of 4 additional programs to support testing: + +1. `hack/emit-metrics.py` to generate random CPU and RAM metrics for every pod in the local cluster. +2. Prometheus Pushgateway to accept metrics from `hack/emit-metrics`. +3. Prometheus to store the metrics accepted by the Pushgateway. +4. Prometheus Adapter to provide an External Metrics interface to Prometheus. + +The External Metrics tests run by configuring a `recommender` to use the External Metrics interface +from the Prometheus Adapter. With that configuration, it runs the standard `recommender` test suite. + +## Non-recommender tests +The `recommender` and `recommender-externalmetrics` test work locally, but none of the others do; +they require more Makefile work. + +# Configuration Notes +To support the regular `recommender` tests locally, we've added the stock Kubernetes Metrics Server. +Unfortunately, it doesn't work with TLS turned on. The metrics server is being run in insecure mode +to work around this. This only runs in the local `kind` case, not in a real cluster. + +# RBAC Changes +The local test cases support running the `recommender` with external metrics. This requires +additional permissions we don't want to automatically enable for all customers via the +configuration given in `deploy/mpa-rbac.yaml`. The scripts use a context diff `hack/e2e/mpa-rbac.diff` +to enable those permission when running locally. diff --git a/multidimensional-pod-autoscaler/deploy/mpa-down.sh b/multidimensional-pod-autoscaler/hack/mpa-down.sh similarity index 93% rename from multidimensional-pod-autoscaler/deploy/mpa-down.sh rename to multidimensional-pod-autoscaler/hack/mpa-down.sh index 053145a18914..d83659930483 100755 --- a/multidimensional-pod-autoscaler/deploy/mpa-down.sh +++ b/multidimensional-pod-autoscaler/hack/mpa-down.sh @@ -20,4 +20,4 @@ set -o pipefail SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. -$SCRIPT_ROOT/deploy/mpa-process-yamls.sh delete $* +$SCRIPT_ROOT/hack/mpa-process-yamls.sh delete $* diff --git a/multidimensional-pod-autoscaler/deploy/mpa-process-yamls.sh b/multidimensional-pod-autoscaler/hack/mpa-process-yamls.sh similarity index 100% rename from multidimensional-pod-autoscaler/deploy/mpa-process-yamls.sh rename to multidimensional-pod-autoscaler/hack/mpa-process-yamls.sh diff --git a/multidimensional-pod-autoscaler/deploy/mpa-up.sh b/multidimensional-pod-autoscaler/hack/mpa-up.sh similarity index 93% rename from multidimensional-pod-autoscaler/deploy/mpa-up.sh rename to multidimensional-pod-autoscaler/hack/mpa-up.sh index 9725ee7643ae..2bbf22b40985 100755 --- a/multidimensional-pod-autoscaler/deploy/mpa-up.sh +++ b/multidimensional-pod-autoscaler/hack/mpa-up.sh @@ -20,4 +20,4 @@ set -o pipefail SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. -$SCRIPT_ROOT/deploy/mpa-process-yamls.sh create $* \ No newline at end of file +$SCRIPT_ROOT/hack/mpa-process-yamls.sh create $* \ No newline at end of file diff --git a/multidimensional-pod-autoscaler/hack/run-e2e-locally.sh b/multidimensional-pod-autoscaler/hack/run-e2e-locally.sh new file mode 100755 index 000000000000..7ea3b3db8144 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/run-e2e-locally.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# Copyright 2023 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. + +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. + +function print_help { + echo "ERROR! Usage: run-e2e.sh " + echo " should be one of:" + echo " - recommender" + echo " - recommender-externalmetrics" +} + +if [ $# -eq 0 ]; then + print_help + exit 1 +fi + +if [ $# -gt 1 ]; then + print_help + exit 1 +fi + +SUITE=$1 + +echo "Deleting KIND cluster 'kind'." +kind delete cluster -n kind -q + +echo "Creating KIND cluster 'kind' with builtin registry." +${SCRIPT_ROOT}/hack/e2e/kind-with-registry.sh + +echo "Building metrics-pump image" +docker build -t localhost:5001/write-metrics:dev -f ${SCRIPT_ROOT}/hack/e2e/Dockerfile.externalmetrics-writer ${SCRIPT_ROOT}/hack +echo " pushing image to local registry" +docker push localhost:5001/write-metrics:dev + +case ${SUITE} in + recommender|recommender-externalmetrics) + ${SCRIPT_ROOT}/hack/mpa-down.sh + echo " ** Deploying for suite ${SUITE}" + ${SCRIPT_ROOT}/hack/deploy-for-e2e-locally.sh ${SUITE} + + echo " ** Running suite ${SUITE}" + if [ ${SUITE} == recommender-externalmetrics ]; then + ${SCRIPT_ROOT}/hack/run-e2e-tests.sh recommender + else + ${SCRIPT_ROOT}/hack/run-e2e-tests.sh ${SUITE} + fi + ;; + *) + print_help + exit 1 + ;; +esac diff --git a/multidimensional-pod-autoscaler/hack/run-e2e-tests.sh b/multidimensional-pod-autoscaler/hack/run-e2e-tests.sh new file mode 100755 index 000000000000..2d9acef0db46 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/run-e2e-tests.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# Copyright 2018 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. + +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. + +function print_help { + echo "ERROR! Usage: run-e2e-tests.sh " + echo " should be one of:" + echo " - recommender" + echo " - updater" + echo " - admission-controller" + echo " - actuation" + echo " - full-mpa" +} + + +if [ $# -eq 0 ]; then + print_help + exit 1 +fi + +if [ $# -gt 1 ]; then + print_help + exit 1 +fi + +SUITE=$1 + +export GO111MODULE=on + +case ${SUITE} in + recommender|updater|admission-controller|actuation|full-mpa) + export KUBECONFIG=$HOME/.kube/config + pushd ${SCRIPT_ROOT}/e2e + go test -mod vendor ./v1beta2/*go -v --test.timeout=90m --args --ginkgo.v=true --ginkgo.focus="\[MPA\] \[${SUITE}\]" --report-dir=/workspace/_artifacts --disable-log-dump --ginkgo.timeout=90m + V1BETA2_RESULT=$? + go test -mod vendor ./v1/*go -v --test.timeout=90m --args --ginkgo.v=true --ginkgo.focus="\[MPA\] \[${SUITE}\]" --report-dir=/workspace/_artifacts --disable-log-dump --ginkgo.timeout=90m + V1_RESULT=$? + popd + echo v1beta2 test result: ${V1BETA2_RESULT} + if [ $V1BETA2_RESULT -gt 0 ]; then + echo "Please check v1beta2 \"go test\" logs!" + fi + echo v1 test result: ${V1_RESULT} + if [ $V1_RESULT -gt 0 ]; then + echo "Please check v1 \"go test\" logs!" + fi + if [ $V1BETA2_RESULT -gt 0 ] || [ $V1_RESULT -gt 0 ]; then + echo "Tests failed" + exit 1 + fi + ;; + *) + print_help + exit 1 + ;; +esac diff --git a/multidimensional-pod-autoscaler/hack/run-e2e.sh b/multidimensional-pod-autoscaler/hack/run-e2e.sh new file mode 100755 index 000000000000..29280b15d0cf --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/run-e2e.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# Copyright 2018 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. + +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. + +function print_help { + echo "ERROR! Usage: run-e2e.sh " + echo " should be one of:" + echo " - recommender" + echo " - updater" + echo " - admission-controller" + echo " - actuation" + echo " - full-mpa" +} + +if [ $# -eq 0 ]; then + print_help + exit 1 +fi + +if [ $# -gt 1 ]; then + print_help + exit 1 +fi + +SUITE=$1 + +case ${SUITE} in + recommender|updater|admission-controller|actuation|full-mpa) + ${SCRIPT_ROOT}/hack/mpa-down.sh + ${SCRIPT_ROOT}/hack/deploy-for-e2e.sh ${SUITE} + ${SCRIPT_ROOT}/hack/run-e2e-tests.sh ${SUITE} + ;; + *) + print_help + exit 1 + ;; +esac diff --git a/multidimensional-pod-autoscaler/hack/update-codegen.sh b/multidimensional-pod-autoscaler/hack/update-codegen.sh new file mode 100755 index 000000000000..f1d006c12bc8 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/update-codegen.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Copyright 2018 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. + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/.. +CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../../code-generator)} + +# generate the code with: +# --output-base because this script should also be able to run inside the vendor dir of +# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir +# instead of the $GOPATH directly. For normal projects this can be dropped. +${CODEGEN_PKG}/generate-groups.sh all \ + k8s.io/autoscaler/multidimensional-pod-autoscaler/pkg/client k8s.io/autoscaler/multidimensional-pod-autoscaler/pkg/apis \ + "autoscaling.k8s.io:v1alpha1" \ + --output-base "$(dirname ${BASH_SOURCE})/../../../.." \ + --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt + +# To use your own boilerplate text append: +# --go-header-file ${SCRIPT_ROOT}/hack/custom-boilerplate.go.txt diff --git a/multidimensional-pod-autoscaler/hack/update-kubernetes-deps-in-e2e.sh b/multidimensional-pod-autoscaler/hack/update-kubernetes-deps-in-e2e.sh new file mode 100755 index 000000000000..5b1e0dac1d97 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/update-kubernetes-deps-in-e2e.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# Copyright 2019 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. + +# Usage: +# $ K8S_TAG= ./hack/update-kubernetes-deps-in-e2e.sh +# K8S_TAG - k8s version to use for the dependencies update. +# Suggested format is K8S_TAG=v1.10.3 + +set -euo pipefail + +K8S_TAG=${K8S_TAG:-v1.25.0} +K8S_TAG=${K8S_TAG#v} +K8S_FORK="git@github.com:kubernetes/kubernetes.git" + +export GO111MODULE=on + +function update_deps() { + # list staged k8s.io repos + MODS=($( + curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${K8S_TAG}/go.mod | + sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' + )) + + # get matching tag for each staged k8s.io repo + for MOD in "${MODS[@]}"; do + V=$( + go mod download -json "${MOD}@kubernetes-${K8S_TAG}" | + sed -n 's|.*"Version": "\(.*\)".*|\1|p' + ) + echo "Replacing ${MOD} with version ${V}" + go mod edit "-replace=${MOD}=${MOD}@${V}" + done +} + +# execute in subshell to keep CWD even in case of failures +( + # find script directory invariantly of CWD + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + + # cd to e2e tests + cd ${DIR}/../e2e + + echo "Updating MPA e2e dependencies to k8s ${K8S_TAG}" + update_deps + + echo "Updating k8s to ${K8S_TAG}" + go get "k8s.io/kubernetes@v${K8S_TAG}" + + echo "Running go mod tidy and vendoring deps" + # tidy and vendor modules + go mod tidy + go mod vendor +) diff --git a/multidimensional-pod-autoscaler/hack/update-kubernetes-deps.sh b/multidimensional-pod-autoscaler/hack/update-kubernetes-deps.sh new file mode 100755 index 000000000000..b9b41d1f480d --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/update-kubernetes-deps.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# Copyright 2023 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. + +# Usage: +# $ K8S_TAG= ./hack/update-kubernetes-deps-in-e2e.sh +# K8S_TAG - k8s version to use for the dependencies update. +# Suggested format is K8S_TAG=v1.10.3 + +set -euo pipefail + +K8S_TAG=${K8S_TAG:-v1.26.1} +K8S_TAG=${K8S_TAG#v} +K8S_FORK="git@github.com:kubernetes/kubernetes.git" + +export GO111MODULE=on + +function update_deps() { + # list staged k8s.io repos + MODS=($( + curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${K8S_TAG}/go.mod | + sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' + )) + + # get matching tag for each staged k8s.io repo + for MOD in "${MODS[@]}"; do + V=$( + go mod download -json "${MOD}@kubernetes-${K8S_TAG}" | + sed -n 's|.*"Version": "\(.*\)".*|\1|p' + ) + echo "Replacing ${MOD} with version ${V}" + go mod edit "-replace=${MOD}=${MOD}@${V}" + done +} + +# execute in subshell to keep CWD even in case of failures +( + # find script directory invariantly of CWD + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + + # cd to e2e tests + cd ${DIR}/.. + + echo "Updating MPA dependencies to k8s ${K8S_TAG}" + update_deps + + echo "Updating k8s to ${K8S_TAG}" + go get "k8s.io/kubernetes@v${K8S_TAG}" + + echo "Running go mod tidy and vendoring deps" + # tidy and vendor modules + go mod tidy + go mod vendor +) diff --git a/multidimensional-pod-autoscaler/hack/verify-codegen.sh b/multidimensional-pod-autoscaler/hack/verify-codegen.sh new file mode 100755 index 000000000000..9cc02a5a4a27 --- /dev/null +++ b/multidimensional-pod-autoscaler/hack/verify-codegen.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Copyright 2017 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. + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/.. + +DIFFROOT="${SCRIPT_ROOT}/pkg" +TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp/pkg" +_tmp="${SCRIPT_ROOT}/_tmp" + +cleanup() { + rm -rf "${_tmp}" +} +trap "cleanup" EXIT SIGINT + +cleanup + +mkdir -p "${TMP_DIFFROOT}" +cp -a "${DIFFROOT}"/* "${TMP_DIFFROOT}" + +"${SCRIPT_ROOT}/hack/update-codegen.sh" +echo "diffing ${DIFFROOT} against freshly generated codegen" +ret=0 +diff -Naupr "${DIFFROOT}" "${TMP_DIFFROOT}" || ret=$? +cp -a "${TMP_DIFFROOT}"/* "${DIFFROOT}" +if [[ $ret -eq 0 ]] +then + echo "${DIFFROOT} up to date." +else + echo "${DIFFROOT} is out of date. Please run hack/update-codegen.sh" + exit 1 +fi