Skip to content

Commit

Permalink
Feat/autoscale container metrics (#160)
Browse files Browse the repository at this point in the history
* feat: container metrics HPA

* test: container metrics HPA
  • Loading branch information
crgisch authored Jan 22, 2025
1 parent 6d27072 commit 59c00c1
Show file tree
Hide file tree
Showing 4 changed files with 813 additions and 30 deletions.
66 changes: 59 additions & 7 deletions controllers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -702,25 +702,32 @@ func isAutoscaleEnabled(instance *v1alpha1.RpaasInstanceSpec) bool {
return !instance.Shutdown && isAutoscaleValid(instance.Autoscale)
}

func buildMetadataForScaledObject(instance *v1alpha1.RpaasInstance, value string) map[string]string {
metadata := map[string]string{
"value": value,
}
if len(instance.Spec.PodTemplate.Containers) > 0 {
metadata["containerName"] = "nginx"
}

return metadata
}

func newKEDAScaledObject(instance *v1alpha1.RpaasInstance, nginx *nginxv1alpha1.Nginx) (*kedav1alpha1.ScaledObject, error) {
var triggers []kedav1alpha1.ScaleTriggers
if instance.Spec.Autoscale != nil && instance.Spec.Autoscale.TargetCPUUtilizationPercentage != nil {
triggers = append(triggers, kedav1alpha1.ScaleTriggers{
Type: "cpu",
MetricType: autoscalingv2.UtilizationMetricType,
Metadata: map[string]string{
"value": strconv.Itoa(int(*instance.Spec.Autoscale.TargetCPUUtilizationPercentage)),
},
Metadata: buildMetadataForScaledObject(instance, strconv.Itoa(int(*instance.Spec.Autoscale.TargetCPUUtilizationPercentage))),
})
}

if instance.Spec.Autoscale != nil && instance.Spec.Autoscale.TargetMemoryUtilizationPercentage != nil {
triggers = append(triggers, kedav1alpha1.ScaleTriggers{
Type: "memory",
MetricType: autoscalingv2.UtilizationMetricType,
Metadata: map[string]string{
"value": strconv.Itoa(int(*instance.Spec.Autoscale.TargetMemoryUtilizationPercentage)),
},
Metadata: buildMetadataForScaledObject(instance, strconv.Itoa(int(*instance.Spec.Autoscale.TargetMemoryUtilizationPercentage))),
})
}

Expand Down Expand Up @@ -1347,9 +1354,48 @@ func generateSpecHash(spec any) (string, error) {
return strings.ToLower(base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(hash[:])), nil
}

func newHPA(instance *v1alpha1.RpaasInstance, nginx *nginxv1alpha1.Nginx) *autoscalingv2.HorizontalPodAutoscaler {
func buildNGNIXContainerMetrics(instance *v1alpha1.RpaasInstance) []autoscalingv2.MetricSpec {
var metrics []autoscalingv2.MetricSpec

if a := instance.Spec.Autoscale; a != nil && a.TargetCPUUtilizationPercentage != nil {
metrics = append(metrics, autoscalingv2.MetricSpec{
Type: autoscalingv2.ContainerResourceMetricSourceType,
ContainerResource: &autoscalingv2.ContainerResourceMetricSource{
Name: corev1.ResourceCPU,
Container: "nginx",
Target: autoscalingv2.MetricTarget{
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: instance.Spec.Autoscale.TargetCPUUtilizationPercentage,
},
},
})
}

if a := instance.Spec.Autoscale; a != nil && a.TargetMemoryUtilizationPercentage != nil {
metrics = append(metrics, autoscalingv2.MetricSpec{
Type: autoscalingv2.ContainerResourceMetricSourceType,
ContainerResource: &autoscalingv2.ContainerResourceMetricSource{
Name: corev1.ResourceMemory,
Container: "nginx",
Target: autoscalingv2.MetricTarget{
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: instance.Spec.Autoscale.TargetMemoryUtilizationPercentage,
},
},
})
}

return metrics
}

func buildHPAMetrics(instance *v1alpha1.RpaasInstance) []autoscalingv2.MetricSpec {
var metrics []autoscalingv2.MetricSpec

if len(instance.Spec.PodTemplate.Containers) > 0 {
//only look at nginx container metrics if there are multiple containers
return buildNGNIXContainerMetrics(instance)
}

if a := instance.Spec.Autoscale; a != nil && a.TargetCPUUtilizationPercentage != nil {
metrics = append(metrics, autoscalingv2.MetricSpec{
Type: autoscalingv2.ResourceMetricSourceType,
Expand All @@ -1376,6 +1422,12 @@ func newHPA(instance *v1alpha1.RpaasInstance, nginx *nginxv1alpha1.Nginx) *autos
})
}

return metrics
}

func newHPA(instance *v1alpha1.RpaasInstance, nginx *nginxv1alpha1.Nginx) *autoscalingv2.HorizontalPodAutoscaler {
metrics := buildHPAMetrics(instance)

minReplicas := instance.Spec.Replicas
if a := instance.Spec.Autoscale; a != nil && a.MinReplicas != nil {
minReplicas = a.MinReplicas
Expand Down
Loading

0 comments on commit 59c00c1

Please sign in to comment.