From 37c9ec05839f693f11ca3208bb8de2685ff44aff Mon Sep 17 00:00:00 2001 From: puzhihao Date: Fri, 15 Nov 2024 17:22:31 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E6=94=AF=E6=8C=81Prometheus=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../autoscaler/autoscaler_controller.go | 8 ++-- pkg/controller/controller_utils.go | 46 ++++++++++++++----- pkg/controller/types.go | 7 +-- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/pkg/controller/autoscaler/autoscaler_controller.go b/pkg/controller/autoscaler/autoscaler_controller.go index 4ef8a87..cbb67d4 100644 --- a/pkg/controller/autoscaler/autoscaler_controller.go +++ b/pkg/controller/autoscaler/autoscaler_controller.go @@ -85,7 +85,7 @@ func NewAutoscalerController( eventBroadcaster.StartLogging(klog.Infof) eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: client.CoreV1().Events("")}) - if client != nil && client.CoreV1().RESTClient().GetRateLimiter() != nil { + if client.CoreV1().RESTClient().GetRateLimiter() != nil { if err := ratelimiter.RegisterMetricAndTrackRateLimiterUsage("pixiu_autoscaler", client.CoreV1().RESTClient().GetRateLimiter()); err != nil { return nil, err } @@ -215,7 +215,6 @@ func (ac *AutoscalerController) sync(d *appsv1.Deployment, hpaList []*autoscalin if !ac.IsDeploymentControlHPA(d) { return ac.deleteHPAsInBatch(hpaList) } - newHPA, err := controller.CreateHPAFromDeployment(d) if err != nil { ac.eventRecorder.Eventf(d, v1.EventTypeWarning, "FailedNewestHPA", fmt.Sprintf("Failed extract newest HPA %s/%s", d.GetNamespace(), d.GetName())) @@ -241,11 +240,12 @@ func (ac *AutoscalerController) sync(d *appsv1.Deployment, hpaList []*autoscalin klog.V(0).Infof("HPA: %s/%s spec is not changed, no need to updated", newHPA.Namespace, newHPA.Name) return nil } - _, err = ac.client.AutoscalingV2().HorizontalPodAutoscalers(newHPA.Namespace).Update(context.TODO(), newHPA, metav1.UpdateOptions{}) - if !errors.IsNotFound(err) { + _, err := ac.client.AutoscalingV2().HorizontalPodAutoscalers(newHPA.Namespace).Update(context.TODO(), newHPA, metav1.UpdateOptions{}) + if err != nil { ac.eventRecorder.Eventf(newHPA, v1.EventTypeWarning, "FailedUpdateHPA", fmt.Sprintf("Failed to Recover update HPA %s/%s", newHPA.Namespace, newHPA.Name)) return err } + ac.eventRecorder.Eventf(newHPA, v1.EventTypeWarning, "UpdateHPA", fmt.Sprintf("update HPA %s/%s", newHPA.Namespace, newHPA.Name)) } return nil diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index a58dd52..74f9d3d 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -103,7 +103,6 @@ func CreateHPAFromDeployment(d *appsv1.Deployment) (*autoscalingv2.HorizontalPod if err != nil { return nil, fmt.Errorf("parse metric specs from annotations failed: %v", err) } - controller := true blockOwnerDeletion := true // Inject ownerReference label @@ -162,7 +161,7 @@ func getMetricTarget(metricName string) (string, string, error) { return "", "", fmt.Errorf("invalied metric item %s", metricName) } metricType := metricTypeSlice[0] - if metricType != cpu && metricType != memory { + if metricType != cpu && metricType != memory && metricType != prometheus { return "", "", fmt.Errorf("unsupprted metric resource name: %s", metricType) } @@ -177,12 +176,17 @@ func getMetricTarget(metricName string) (string, string, error) { func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec, error) { metricSpecs := make([]autoscalingv2.MetricSpec, 0) - for metricName, metricValue := range annotations { + var metricName string + + for annotationName, annotationValue := range annotations { + if annotationName == prometheusMetricName { + metricName = annotationValue + } // let it go if annotation item are not the target - if !strings.Contains(metricName, PixiuDot+PixiuRootPrefix) { + if !strings.Contains(annotationName, PixiuDot+PixiuRootPrefix) { continue } - metricType, target, err := getMetricTarget(metricName) + metricType, target, err := getMetricTarget(annotationName) if err != nil { return nil, err } @@ -190,7 +194,7 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec var metricSpec autoscalingv2.MetricSpec switch target { case targetAverageUtilization: - averageUtilization, err := extractAverageUtilization(metricValue) + averageUtilization, err := extractAverageUtilization(annotationValue) if err != nil { return nil, err } @@ -204,9 +208,8 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec }, }, } - case targetAverageValue: - averageValue, err := resource.ParseQuantity(metricValue) + averageValue, err := resource.ParseQuantity(annotationValue) if err != nil { return nil, err } @@ -221,12 +224,33 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec }, } } - switch metricType { case cpu: metricSpec.Resource.Name = v1.ResourceCPU case memory: metricSpec.Resource.Name = v1.ResourceMemory + case prometheus: + averageValue, err := resource.ParseQuantity(annotationValue) + if err != nil { + return nil, err + } + metricSpec = autoscalingv2.MetricSpec{ + Type: autoscalingv2.PodsMetricSourceType, + Pods: &autoscalingv2.PodsMetricSource{ + Metric: autoscalingv2.MetricIdentifier{ + Name: metricName, + }, + Target: autoscalingv2.MetricTarget{ + AverageValue: &averageValue, + }, + }, + } + switch target { + case targetAverageUtilization: + metricSpec.Pods.Target.Type = autoscalingv2.UtilizationMetricType + case targetAverageValue: + metricSpec.Pods.Target.Type = autoscalingv2.AverageValueMetricType + } } metricSpecs = append(metricSpecs, metricSpec) @@ -292,7 +316,7 @@ func extractAverageUtilization(averageUtilization string) (int32, error) { if err != nil { return 0, err } - if value64 <= 0 && value64 > 100 { + if value64 <= 0 { return 0, fmt.Errorf("averageUtilization should be range 1 between 100") } @@ -305,7 +329,7 @@ type Empty struct{} func NewItems() map[string]Empty { items := make(map[string]Empty) - for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, cpuAverageValue, memoryAverageValue} { + for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, prometheusAverageUtilization, prometheusAverageValue, cpuAverageValue, memoryAverageValue} { items[k] = Empty{} } diff --git a/pkg/controller/types.go b/pkg/controller/types.go index 7b4c7a6..75a1c05 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -29,9 +29,10 @@ const ( targetAverageValue string = "targetAverageValue" // TODO: prometheus is not supported for now. - cpu string = "cpu" - memory string = "memory" - prometheus string = "prometheus" + cpu string = "cpu" + memory string = "memory" + prometheus string = "prometheus" + prometheusMetricName = PixiuRootPrefix + PixiuSeparator + "metricName" cpuAverageUtilization = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization From 17faa55004d5641ed35d7fc3c644a3b459b1337c Mon Sep 17 00:00:00 2001 From: puzhihao Date: Fri, 15 Nov 2024 17:29:36 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E6=94=AF=E6=8C=81Prometheus=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/controller/controller_utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index 74f9d3d..7ad641e 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -316,7 +316,7 @@ func extractAverageUtilization(averageUtilization string) (int32, error) { if err != nil { return 0, err } - if value64 <= 0 { + if value64 <= 0 && value64 > 100 { return 0, fmt.Errorf("averageUtilization should be range 1 between 100") } From 6424d30ffc98e7adf7d531d1f46727e3349be3fd Mon Sep 17 00:00:00 2001 From: puzhihao Date: Fri, 15 Nov 2024 17:33:50 +0800 Subject: [PATCH 03/13] =?UTF-8?q?=E6=94=AF=E6=8C=81Prometheus=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/controller/autoscaler/autoscaler_controller.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/controller/autoscaler/autoscaler_controller.go b/pkg/controller/autoscaler/autoscaler_controller.go index cbb67d4..ba53e61 100644 --- a/pkg/controller/autoscaler/autoscaler_controller.go +++ b/pkg/controller/autoscaler/autoscaler_controller.go @@ -85,7 +85,7 @@ func NewAutoscalerController( eventBroadcaster.StartLogging(klog.Infof) eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: client.CoreV1().Events("")}) - if client.CoreV1().RESTClient().GetRateLimiter() != nil { + if client != nil && client.CoreV1().RESTClient().GetRateLimiter() != nil { if err := ratelimiter.RegisterMetricAndTrackRateLimiterUsage("pixiu_autoscaler", client.CoreV1().RESTClient().GetRateLimiter()); err != nil { return nil, err } @@ -240,14 +240,13 @@ func (ac *AutoscalerController) sync(d *appsv1.Deployment, hpaList []*autoscalin klog.V(0).Infof("HPA: %s/%s spec is not changed, no need to updated", newHPA.Namespace, newHPA.Name) return nil } - _, err := ac.client.AutoscalingV2().HorizontalPodAutoscalers(newHPA.Namespace).Update(context.TODO(), newHPA, metav1.UpdateOptions{}) + _, err = ac.client.AutoscalingV2().HorizontalPodAutoscalers(newHPA.Namespace).Update(context.TODO(), newHPA, metav1.UpdateOptions{}) if err != nil { ac.eventRecorder.Eventf(newHPA, v1.EventTypeWarning, "FailedUpdateHPA", fmt.Sprintf("Failed to Recover update HPA %s/%s", newHPA.Namespace, newHPA.Name)) return err } ac.eventRecorder.Eventf(newHPA, v1.EventTypeWarning, "UpdateHPA", fmt.Sprintf("update HPA %s/%s", newHPA.Namespace, newHPA.Name)) } - return nil } From abde83e4bf877fcb43ff3ba4ceddec01134bed14 Mon Sep 17 00:00:00 2001 From: puzhihao Date: Fri, 15 Nov 2024 17:37:06 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E6=94=AF=E6=8C=81Prometheus=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/controller/autoscaler/autoscaler_controller.go | 2 ++ pkg/controller/controller_utils.go | 3 +++ 2 files changed, 5 insertions(+) diff --git a/pkg/controller/autoscaler/autoscaler_controller.go b/pkg/controller/autoscaler/autoscaler_controller.go index ba53e61..cb5f111 100644 --- a/pkg/controller/autoscaler/autoscaler_controller.go +++ b/pkg/controller/autoscaler/autoscaler_controller.go @@ -215,6 +215,7 @@ func (ac *AutoscalerController) sync(d *appsv1.Deployment, hpaList []*autoscalin if !ac.IsDeploymentControlHPA(d) { return ac.deleteHPAsInBatch(hpaList) } + newHPA, err := controller.CreateHPAFromDeployment(d) if err != nil { ac.eventRecorder.Eventf(d, v1.EventTypeWarning, "FailedNewestHPA", fmt.Sprintf("Failed extract newest HPA %s/%s", d.GetNamespace(), d.GetName())) @@ -247,6 +248,7 @@ func (ac *AutoscalerController) sync(d *appsv1.Deployment, hpaList []*autoscalin } ac.eventRecorder.Eventf(newHPA, v1.EventTypeWarning, "UpdateHPA", fmt.Sprintf("update HPA %s/%s", newHPA.Namespace, newHPA.Name)) } + return nil } diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index 7ad641e..eaa8cab 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -103,6 +103,7 @@ func CreateHPAFromDeployment(d *appsv1.Deployment) (*autoscalingv2.HorizontalPod if err != nil { return nil, fmt.Errorf("parse metric specs from annotations failed: %v", err) } + controller := true blockOwnerDeletion := true // Inject ownerReference label @@ -208,6 +209,7 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec }, }, } + case targetAverageValue: averageValue, err := resource.ParseQuantity(annotationValue) if err != nil { @@ -224,6 +226,7 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec }, } } + switch metricType { case cpu: metricSpec.Resource.Name = v1.ResourceCPU From 0d3fb68c44749f7f0e0e2d2a26e0fd83a8279f37 Mon Sep 17 00:00:00 2001 From: caoyingjunz Date: Sun, 17 Nov 2024 11:33:36 +0800 Subject: [PATCH 05/13] add --- pkg/controller/controller_utils.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index eaa8cab..84c7ea6 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -177,17 +177,12 @@ func getMetricTarget(metricName string) (string, string, error) { func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec, error) { metricSpecs := make([]autoscalingv2.MetricSpec, 0) - var metricName string - - for annotationName, annotationValue := range annotations { - if annotationName == prometheusMetricName { - metricName = annotationValue - } + for metricName, metricValue := range annotations { // let it go if annotation item are not the target - if !strings.Contains(annotationName, PixiuDot+PixiuRootPrefix) { + if !strings.Contains(metricName, PixiuDot+PixiuRootPrefix) { continue } - metricType, target, err := getMetricTarget(annotationName) + metricType, target, err := getMetricTarget(metricName) if err != nil { return nil, err } @@ -195,7 +190,7 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec var metricSpec autoscalingv2.MetricSpec switch target { case targetAverageUtilization: - averageUtilization, err := extractAverageUtilization(annotationValue) + averageUtilization, err := extractAverageUtilization(metricValue) if err != nil { return nil, err } @@ -211,7 +206,7 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec } case targetAverageValue: - averageValue, err := resource.ParseQuantity(annotationValue) + averageValue, err := resource.ParseQuantity(metricValue) if err != nil { return nil, err } @@ -233,15 +228,20 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec case memory: metricSpec.Resource.Name = v1.ResourceMemory case prometheus: - averageValue, err := resource.ParseQuantity(annotationValue) + averageValue, err := resource.ParseQuantity(metricValue) if err != nil { return nil, err } + name, ok := annotations[prometheusMetricName] + if !ok { + return nil, fmt.Errorf("failed to get pod metric name") + } + metricSpec = autoscalingv2.MetricSpec{ Type: autoscalingv2.PodsMetricSourceType, Pods: &autoscalingv2.PodsMetricSource{ Metric: autoscalingv2.MetricIdentifier{ - Name: metricName, + Name: name, }, Target: autoscalingv2.MetricTarget{ AverageValue: &averageValue, From 515bf251acc179ae919ef0e1296ab0f877d521be Mon Sep 17 00:00:00 2001 From: caoyingjunz Date: Sun, 17 Nov 2024 11:35:49 +0800 Subject: [PATCH 06/13] add --- pkg/controller/types.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/controller/types.go b/pkg/controller/types.go index 75a1c05..78c2c63 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -28,11 +28,11 @@ const ( targetAverageUtilization string = "targetAverageUtilization" targetAverageValue string = "targetAverageValue" - // TODO: prometheus is not supported for now. - cpu string = "cpu" - memory string = "memory" - prometheus string = "prometheus" - prometheusMetricName = PixiuRootPrefix + PixiuSeparator + "metricName" + cpu string = "cpu" + memory string = "memory" + prometheus string = "prometheus" + + prometheusMetricName = PixiuRootPrefix + PixiuSeparator + "metricName" cpuAverageUtilization = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization From f36c8a568ce6f146958f616a182948c30ae470d7 Mon Sep 17 00:00:00 2001 From: caoyingjunz Date: Sun, 17 Nov 2024 13:41:40 +0800 Subject: [PATCH 07/13] add --- pkg/controller/types.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/controller/types.go b/pkg/controller/types.go index 78c2c63..c693c2c 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -32,12 +32,13 @@ const ( memory string = "memory" prometheus string = "prometheus" - prometheusMetricName = PixiuRootPrefix + PixiuSeparator + "metricName" - cpuAverageUtilization = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization prometheusAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization + // 指标来着 prometheus 时,需要指定指标名称 + prometheusMetricName = PixiuRootPrefix + PixiuSeparator + "targetCustomMetric" + // CPU, in cores. (500m = .5 cores) // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) cpuAverageValue = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageValue From 31c77d55f6bdbaaf82d0af33cd926e32ae0ba8cd Mon Sep 17 00:00:00 2001 From: caoyingjunz Date: Sun, 17 Nov 2024 13:57:10 +0800 Subject: [PATCH 08/13] add --- pkg/controller/controller_utils.go | 4 ++-- pkg/controller/types.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index 84c7ea6..f5d17c7 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -232,9 +232,9 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec if err != nil { return nil, err } - name, ok := annotations[prometheusMetricName] + name, ok := annotations[prometheusCustomMetric] if !ok { - return nil, fmt.Errorf("failed to get pod metric name") + return nil, fmt.Errorf("failed to get targetCustomMetric from annotations") } metricSpec = autoscalingv2.MetricSpec{ diff --git a/pkg/controller/types.go b/pkg/controller/types.go index c693c2c..8ddaedc 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -37,7 +37,7 @@ const ( prometheusAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization // 指标来着 prometheus 时,需要指定指标名称 - prometheusMetricName = PixiuRootPrefix + PixiuSeparator + "targetCustomMetric" + prometheusCustomMetric = PixiuRootPrefix + PixiuSeparator + "targetCustomMetric" // CPU, in cores. (500m = .5 cores) // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) From fbea7bac8d6706f380042fe4fe0fc03f9d1a59d2 Mon Sep 17 00:00:00 2001 From: puzhihao Date: Mon, 18 Nov 2024 16:08:06 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E6=94=AF=E6=8C=81Prometheus=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/controller/controller_utils.go | 31 ++++++++++++++++++++++++++++-- pkg/controller/types.go | 3 +++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index 5172882..542069e 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -162,7 +162,7 @@ func getMetricTarget(metricName string) (string, string, error) { return "", "", fmt.Errorf("invalied metric item %s", metricName) } metricType := metricTypeSlice[0] - if metricType != cpu && metricType != memory { + if metricType != cpu && metricType != memory && metricType != prometheus { return "", "", fmt.Errorf("unsupprted metric resource name: %s", metricType) } @@ -227,6 +227,33 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec metricSpec.Resource.Name = v1.ResourceCPU case memory: metricSpec.Resource.Name = v1.ResourceMemory + case prometheus: + averageValue, err := resource.ParseQuantity(metricValue) + if err != nil { + return nil, err + } + name, ok := annotations[prometheusCustomMetric] + if !ok { + return nil, fmt.Errorf("failed to get targetCustomMetric from annotations") + } + + metricSpec = autoscalingv2.MetricSpec{ + Type: autoscalingv2.PodsMetricSourceType, + Pods: &autoscalingv2.PodsMetricSource{ + Metric: autoscalingv2.MetricIdentifier{ + Name: name, + }, + Target: autoscalingv2.MetricTarget{ + AverageValue: &averageValue, + }, + }, + } + switch target { + case targetAverageUtilization: + metricSpec.Pods.Target.Type = autoscalingv2.UtilizationMetricType + case targetAverageValue: + metricSpec.Pods.Target.Type = autoscalingv2.AverageValueMetricType + } } metricSpecs = append(metricSpecs, metricSpec) @@ -306,7 +333,7 @@ type Empty struct{} func NewItems() map[string]Empty { items := make(map[string]Empty) - for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, cpuAverageValue, memoryAverageValue} { + for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, prometheusAverageUtilization, cpuAverageValue, memoryAverageValue, prometheusAverageValue} { items[k] = Empty{} } diff --git a/pkg/controller/types.go b/pkg/controller/types.go index 7b4c7a6..ddb97fb 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -37,6 +37,9 @@ const ( memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization prometheusAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization + // When the metrics come from Prometheus, the metric name needs to be specified. + prometheusCustomMetric = PixiuRootPrefix + PixiuSeparator + "targetCustomMetric" + // CPU, in cores. (500m = .5 cores) // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) cpuAverageValue = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageValue From c887bad202f13a40d1124b7bb6f74fb94c398d11 Mon Sep 17 00:00:00 2001 From: puzhihao Date: Mon, 18 Nov 2024 17:39:51 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E6=94=AF=E6=8C=81Prometheus=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/controller/controller_utils.go | 45 +++++++++++++++++++++--------- pkg/controller/types.go | 22 ++++++++------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index 542069e..7ec0fad 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -220,14 +220,8 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec }, }, } - } - switch metricType { - case cpu: - metricSpec.Resource.Name = v1.ResourceCPU - case memory: - metricSpec.Resource.Name = v1.ResourceMemory - case prometheus: + case podsTargetAverageUtilization: averageValue, err := resource.ParseQuantity(metricValue) if err != nil { return nil, err @@ -245,17 +239,42 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec }, Target: autoscalingv2.MetricTarget{ AverageValue: &averageValue, + Type: autoscalingv2.UtilizationMetricType, }, }, } - switch target { - case targetAverageUtilization: - metricSpec.Pods.Target.Type = autoscalingv2.UtilizationMetricType - case targetAverageValue: - metricSpec.Pods.Target.Type = autoscalingv2.AverageValueMetricType + + case podsTargetAverageValue: + averageValue, err := resource.ParseQuantity(metricValue) + if err != nil { + return nil, err + } + name, ok := annotations[prometheusCustomMetric] + if !ok { + return nil, fmt.Errorf("failed to get targetCustomMetric from annotations") + } + + metricSpec = autoscalingv2.MetricSpec{ + Type: autoscalingv2.PodsMetricSourceType, + Pods: &autoscalingv2.PodsMetricSource{ + Metric: autoscalingv2.MetricIdentifier{ + Name: name, + }, + Target: autoscalingv2.MetricTarget{ + AverageValue: &averageValue, + Type: autoscalingv2.AverageValueMetricType, + }, + }, } } + switch metricType { + case cpu: + metricSpec.Resource.Name = v1.ResourceCPU + case memory: + metricSpec.Resource.Name = v1.ResourceMemory + } + metricSpecs = append(metricSpecs, metricSpec) } @@ -333,7 +352,7 @@ type Empty struct{} func NewItems() map[string]Empty { items := make(map[string]Empty) - for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, prometheusAverageUtilization, cpuAverageValue, memoryAverageValue, prometheusAverageValue} { + for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, podsAverageUtilization, cpuAverageValue, memoryAverageValue, podsAverageValue} { items[k] = Empty{} } diff --git a/pkg/controller/types.go b/pkg/controller/types.go index ddb97fb..9aafe2c 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -23,28 +23,30 @@ const ( PixiuSeparator string = "/" PixiuDot string = "." - MinReplicas string = "hpa.caoyingjunz.io/minReplicas" - MaxReplicas string = "hpa.caoyingjunz.io/maxReplicas" - targetAverageUtilization string = "targetAverageUtilization" - targetAverageValue string = "targetAverageValue" + MinReplicas string = "hpa.caoyingjunz.io/minReplicas" + MaxReplicas string = "hpa.caoyingjunz.io/maxReplicas" + targetAverageUtilization string = "targetAverageUtilization" + targetAverageValue string = "targetAverageValue" + podsTargetAverageUtilization string = "podsTargetAverageUtilization" + podsTargetAverageValue string = "podsTargetAverageValue" // TODO: prometheus is not supported for now. cpu string = "cpu" memory string = "memory" prometheus string = "prometheus" - cpuAverageUtilization = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization - memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization - prometheusAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization + cpuAverageUtilization = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization + memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization + podsAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + podsTargetAverageUtilization // When the metrics come from Prometheus, the metric name needs to be specified. prometheusCustomMetric = PixiuRootPrefix + PixiuSeparator + "targetCustomMetric" // CPU, in cores. (500m = .5 cores) // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) - cpuAverageValue = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageValue - memoryAverageValue = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageValue - prometheusAverageValue = "prometheus." + PixiuRootPrefix + PixiuSeparator + targetAverageValue + cpuAverageValue = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageValue + memoryAverageValue = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageValue + podsAverageValue = "prometheus." + PixiuRootPrefix + PixiuSeparator + podsTargetAverageValue ) const ( From 6432968568387e1392f399e4031882e09ed5f544 Mon Sep 17 00:00:00 2001 From: puzhihao Date: Mon, 18 Nov 2024 17:49:32 +0800 Subject: [PATCH 11/13] =?UTF-8?q?=E6=94=AF=E6=8C=81Prometheus=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/controller/controller_utils.go | 2 +- pkg/controller/types.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index 7ec0fad..0234960 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -352,7 +352,7 @@ type Empty struct{} func NewItems() map[string]Empty { items := make(map[string]Empty) - for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, podsAverageUtilization, cpuAverageValue, memoryAverageValue, podsAverageValue} { + for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, prometheusAverageUtilization, cpuAverageValue, memoryAverageValue, prometheusAverageValue} { items[k] = Empty{} } diff --git a/pkg/controller/types.go b/pkg/controller/types.go index 9aafe2c..9d26b44 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -35,18 +35,18 @@ const ( memory string = "memory" prometheus string = "prometheus" - cpuAverageUtilization = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization - memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization - podsAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + podsTargetAverageUtilization + cpuAverageUtilization = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization + memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization + prometheusAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + podsTargetAverageUtilization // When the metrics come from Prometheus, the metric name needs to be specified. prometheusCustomMetric = PixiuRootPrefix + PixiuSeparator + "targetCustomMetric" // CPU, in cores. (500m = .5 cores) // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) - cpuAverageValue = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageValue - memoryAverageValue = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageValue - podsAverageValue = "prometheus." + PixiuRootPrefix + PixiuSeparator + podsTargetAverageValue + cpuAverageValue = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageValue + memoryAverageValue = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageValue + prometheusAverageValue = "prometheus." + PixiuRootPrefix + PixiuSeparator + podsTargetAverageValue ) const ( From 1620fdaa9586f9c0b87e6b106b20df0c806e752e Mon Sep 17 00:00:00 2001 From: puzhihao Date: Mon, 18 Nov 2024 21:36:26 +0800 Subject: [PATCH 12/13] 123 --- pkg/controller/controller_utils.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index f5d17c7..ffd4f21 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -17,6 +17,7 @@ limitations under the License. package controller import ( + 123 "crypto/md5" "encoding/hex" "fmt" From 1b313b1662249b0cce9b973062d3f07879bb8e9e Mon Sep 17 00:00:00 2001 From: puzhihao Date: Mon, 18 Nov 2024 21:59:41 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E6=94=AF=E6=8C=81Prometheus=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/controller/controller_utils.go | 129 ++++++++++++++++------------- pkg/controller/types.go | 17 ++-- 2 files changed, 78 insertions(+), 68 deletions(-) diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index ffd4f21..7a8785d 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -17,7 +17,6 @@ limitations under the License. package controller import ( - 123 "crypto/md5" "encoding/hex" "fmt" @@ -196,14 +195,38 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec return nil, err } - metricSpec = autoscalingv2.MetricSpec{ - Type: autoscalingv2.ResourceMetricSourceType, - Resource: &autoscalingv2.ResourceMetricSource{ - Target: autoscalingv2.MetricTarget{ - Type: autoscalingv2.UtilizationMetricType, - AverageUtilization: utilpointer.Int32Ptr(averageUtilization), + if metricType == prometheus { + averageValue, err := resource.ParseQuantity(metricValue) + if err != nil { + return nil, err + } + name, ok := annotations[prometheusCustomMetric] + if !ok { + return nil, fmt.Errorf("failed to get targetCustomMetric from annotations") + } + + metricSpec = autoscalingv2.MetricSpec{ + Type: autoscalingv2.PodsMetricSourceType, + Pods: &autoscalingv2.PodsMetricSource{ + Metric: autoscalingv2.MetricIdentifier{ + Name: name, + }, + Target: autoscalingv2.MetricTarget{ + AverageValue: &averageValue, + Type: autoscalingv2.UtilizationMetricType, + }, }, - }, + } + } else { + metricSpec = autoscalingv2.MetricSpec{ + Type: autoscalingv2.ResourceMetricSourceType, + Resource: &autoscalingv2.ResourceMetricSource{ + Target: autoscalingv2.MetricTarget{ + Type: autoscalingv2.UtilizationMetricType, + AverageUtilization: utilpointer.Int32Ptr(averageUtilization), + }, + }, + } } case targetAverageValue: @@ -211,50 +234,41 @@ func parseMetricSpecs(annotations map[string]string) ([]autoscalingv2.MetricSpec if err != nil { return nil, err } - - metricSpec = autoscalingv2.MetricSpec{ - Type: autoscalingv2.ResourceMetricSourceType, - Resource: &autoscalingv2.ResourceMetricSource{ - Target: autoscalingv2.MetricTarget{ - Type: autoscalingv2.AverageValueMetricType, - AverageValue: &averageValue, + if metricType == prometheus { + name, ok := annotations[prometheusCustomMetric] + if !ok { + return nil, fmt.Errorf("failed to get targetCustomMetric from annotations") + } + + metricSpec = autoscalingv2.MetricSpec{ + Type: autoscalingv2.PodsMetricSourceType, + Pods: &autoscalingv2.PodsMetricSource{ + Metric: autoscalingv2.MetricIdentifier{ + Name: name, + }, + Target: autoscalingv2.MetricTarget{ + AverageValue: &averageValue, + Type: autoscalingv2.AverageValueMetricType, + }, + }, + } + } else { + metricSpec = autoscalingv2.MetricSpec{ + Type: autoscalingv2.ResourceMetricSourceType, + Resource: &autoscalingv2.ResourceMetricSource{ + Target: autoscalingv2.MetricTarget{ + Type: autoscalingv2.AverageValueMetricType, + AverageValue: &averageValue, + }, }, - }, + } } } - switch metricType { case cpu: metricSpec.Resource.Name = v1.ResourceCPU case memory: metricSpec.Resource.Name = v1.ResourceMemory - case prometheus: - averageValue, err := resource.ParseQuantity(metricValue) - if err != nil { - return nil, err - } - name, ok := annotations[prometheusCustomMetric] - if !ok { - return nil, fmt.Errorf("failed to get targetCustomMetric from annotations") - } - - metricSpec = autoscalingv2.MetricSpec{ - Type: autoscalingv2.PodsMetricSourceType, - Pods: &autoscalingv2.PodsMetricSource{ - Metric: autoscalingv2.MetricIdentifier{ - Name: name, - }, - Target: autoscalingv2.MetricTarget{ - AverageValue: &averageValue, - }, - }, - } - switch target { - case targetAverageUtilization: - metricSpec.Pods.Target.Type = autoscalingv2.UtilizationMetricType - case targetAverageValue: - metricSpec.Pods.Target.Type = autoscalingv2.AverageValueMetricType - } } metricSpecs = append(metricSpecs, metricSpec) @@ -292,27 +306,28 @@ func ManageByPixiuController(hpa *autoscalingv2.HorizontalPodAutoscaler) bool { } func extractReplicas(annotations map[string]string, replicasType string) (int32, error) { - var Replicas int64 - var err error + var ( + Replicas string + exists bool + ) switch replicasType { case MinReplicas: - minReplicas, exists := annotations[MinReplicas] + Replicas, exists = annotations[MinReplicas] if !exists { - // Default minReplicas is 1 - return 1, nil - } - if Replicas, err = strconv.ParseInt(minReplicas, 10, 32); err != nil { - return 0, err + return 1, nil // Default minReplicas is 1 } case MaxReplicas: - maxReplicas, exists := annotations[MaxReplicas] + Replicas, exists = annotations[MaxReplicas] if !exists { - return 0, fmt.Errorf("%s is required", MaxReplicas) + return 6, nil // Default maxReplicas is 6 } - Replicas, err = strconv.ParseInt(maxReplicas, 10, 32) } - return int32(Replicas), err + targetReplicas, err := strconv.ParseInt(Replicas, 10, 32) + if err != nil { + return 0, err + } + return int32(targetReplicas), err } func extractAverageUtilization(averageUtilization string) (int32, error) { @@ -333,7 +348,7 @@ type Empty struct{} func NewItems() map[string]Empty { items := make(map[string]Empty) - for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, prometheusAverageUtilization, prometheusAverageValue, cpuAverageValue, memoryAverageValue} { + for _, k := range []string{cpuAverageUtilization, memoryAverageUtilization, prometheusAverageUtilization, cpuAverageValue, memoryAverageValue, prometheusAverageValue} { items[k] = Empty{} } diff --git a/pkg/controller/types.go b/pkg/controller/types.go index 8efa9a1..8ddaedc 100644 --- a/pkg/controller/types.go +++ b/pkg/controller/types.go @@ -23,12 +23,10 @@ const ( PixiuSeparator string = "/" PixiuDot string = "." - MinReplicas string = "hpa.caoyingjunz.io/minReplicas" - MaxReplicas string = "hpa.caoyingjunz.io/maxReplicas" - targetAverageUtilization string = "targetAverageUtilization" - targetAverageValue string = "targetAverageValue" - podsTargetAverageUtilization string = "podsTargetAverageUtilization" - podsTargetAverageValue string = "podsTargetAverageValue" + MinReplicas string = "hpa.caoyingjunz.io/minReplicas" + MaxReplicas string = "hpa.caoyingjunz.io/maxReplicas" + targetAverageUtilization string = "targetAverageUtilization" + targetAverageValue string = "targetAverageValue" cpu string = "cpu" memory string = "memory" @@ -36,10 +34,7 @@ const ( cpuAverageUtilization = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization memoryAverageUtilization = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization - prometheusAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + podsTargetAverageUtilization - - // When the metrics come from Prometheus, the metric name needs to be specified. - prometheusCustomMetric = PixiuRootPrefix + PixiuSeparator + "targetCustomMetric" + prometheusAverageUtilization = "prometheus." + PixiuRootPrefix + PixiuSeparator + targetAverageUtilization // 指标来着 prometheus 时,需要指定指标名称 prometheusCustomMetric = PixiuRootPrefix + PixiuSeparator + "targetCustomMetric" @@ -48,7 +43,7 @@ const ( // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) cpuAverageValue = "cpu." + PixiuRootPrefix + PixiuSeparator + targetAverageValue memoryAverageValue = "memory." + PixiuRootPrefix + PixiuSeparator + targetAverageValue - prometheusAverageValue = "prometheus." + PixiuRootPrefix + PixiuSeparator + podsTargetAverageValue + prometheusAverageValue = "prometheus." + PixiuRootPrefix + PixiuSeparator + targetAverageValue ) const (