Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

支持基于Prometheus自定义指标的扩缩容功能 #38

Merged
merged 15 commits into from
Nov 19, 2024
3 changes: 2 additions & 1 deletion pkg/controller/autoscaler/autoscaler_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,11 @@ func (ac *AutoscalerController) sync(d *appsv1.Deployment, hpaList []*autoscalin
return nil
}
_, err = ac.client.AutoscalingV2().HorizontalPodAutoscalers(newHPA.Namespace).Update(context.TODO(), newHPA, metav1.UpdateOptions{})
if !errors.IsNotFound(err) {
caoyingjunz marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down
41 changes: 34 additions & 7 deletions pkg/controller/controller_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -177,20 +177,25 @@ 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
}

var metricSpec autoscalingv2.MetricSpec
switch target {
case targetAverageUtilization:
averageUtilization, err := extractAverageUtilization(metricValue)
averageUtilization, err := extractAverageUtilization(annotationValue)
caoyingjunz marked this conversation as resolved.
Show resolved Hide resolved
caoyingjunz marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
Expand All @@ -206,7 +211,7 @@ 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
}
Expand All @@ -227,6 +232,28 @@ 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(annotationValue)
if err != nil {
return nil, err
caoyingjunz marked this conversation as resolved.
Show resolved Hide resolved
}
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)
Expand Down Expand Up @@ -305,7 +332,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{}
}

Expand Down
7 changes: 4 additions & 3 deletions pkg/controller/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading