Skip to content

Commit

Permalink
feat: add ContainerResource type for HPA cpu/memory scaler (#3513)
Browse files Browse the repository at this point in the history
Signed-off-by: Suresh Kumar <[email protected]>
  • Loading branch information
surki authored Aug 8, 2022
1 parent f216b8b commit acb03ab
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 9 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ To learn more about our roadmap, we recommend reading [this document](ROADMAP.md
- **General:** Use more readable timestamps in KEDA Operator logs ([#3066](https://github.com/kedacore/keda/issue/3066))
- **AWS SQS Queue Scaler:** Support for scaling to include in-flight messages. ([#3133](https://github.com/kedacore/keda/issues/3133))
- **Azure Pipelines Scaler:** Add support for Azure Pipelines to support demands (capabilities) ([#2328](https://github.com/kedacore/keda/issues/2328))
- **CPU/Memory Scaler:** Added support for targeting specific container in a pod ([#1378](https://github.com/kedacore/keda/issues/1378))
- **GCP Stackdriver Scaler:** Added aggregation parameters ([#3008](https://github.com/kedacore/keda/issues/3008))
- **Kafka Scaler:** Handle Sarama errors properly ([#3056](https://github.com/kedacore/keda/issues/3056))
- **Kafka Scaler:** Support of passphrase encrypted PKCS #\8 private key ([3449](https://github.com/kedacore/keda/issues/3449))
- **Prometheus Scaler:** Add ignoreNullValues to return error when prometheus return null in values ([#3065](https://github.com/kedacore/keda/issues/3065))
- **Selenium Grid Scaler:** Edge active sessions not being properly counted ([#2709](https://github.com/kedacore/keda/issues/2709))
- **Selenium Grid Scaler:** Max Sessions implementation issue ([#3061](https://github.com/kedacore/keda/issues/3061))
- **Selenium Grid Scaler:** Max Sessions implementation issue ([#3061](https://github.c>>>>>>> mainom/kedacore/keda/issues/3061))

### Fixes

Expand Down
38 changes: 30 additions & 8 deletions pkg/scalers/cpu_memory_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type cpuMemoryMetadata struct {
Type v2beta2.MetricTargetType
AverageValue *resource.Quantity
AverageUtilization *int32
ContainerName string
}

// NewCPUMemoryScaler creates a new cpuMemoryScaler
Expand Down Expand Up @@ -73,6 +74,11 @@ func parseResourceMetadata(config *ScalerConfig, logger logr.Logger) (*cpuMemory
default:
return nil, fmt.Errorf("unsupported metric type, allowed values are 'Utilization' or 'AverageValue'")
}

if value, ok = config.TriggerMetadata["containerName"]; ok && value != "" {
meta.ContainerName = value
}

return meta, nil
}

Expand All @@ -88,15 +94,31 @@ func (s *cpuMemoryScaler) Close(context.Context) error {

// GetMetricSpecForScaling returns the metric spec for the HPA
func (s *cpuMemoryScaler) GetMetricSpecForScaling(context.Context) []v2beta2.MetricSpec {
cpuMemoryMetric := &v2beta2.ResourceMetricSource{
Name: s.resourceName,
Target: v2beta2.MetricTarget{
Type: s.metadata.Type,
AverageUtilization: s.metadata.AverageUtilization,
AverageValue: s.metadata.AverageValue,
},
var metricSpec v2beta2.MetricSpec

if s.metadata.ContainerName != "" {
containerCPUMemoryMetric := &v2beta2.ContainerResourceMetricSource{
Name: s.resourceName,
Target: v2beta2.MetricTarget{
Type: s.metadata.Type,
AverageUtilization: s.metadata.AverageUtilization,
AverageValue: s.metadata.AverageValue,
},
Container: s.metadata.ContainerName,
}
metricSpec = v2beta2.MetricSpec{ContainerResource: containerCPUMemoryMetric, Type: v2beta2.ContainerResourceMetricSourceType}
} else {
cpuMemoryMetric := &v2beta2.ResourceMetricSource{
Name: s.resourceName,
Target: v2beta2.MetricTarget{
Type: s.metadata.Type,
AverageUtilization: s.metadata.AverageUtilization,
AverageValue: s.metadata.AverageValue,
},
}
metricSpec = v2beta2.MetricSpec{Resource: cpuMemoryMetric, Type: v2beta2.ResourceMetricSourceType}
}
metricSpec := v2beta2.MetricSpec{Resource: cpuMemoryMetric, Type: v2beta2.ResourceMetricSourceType}

return []v2beta2.MetricSpec{metricSpec}
}

Expand Down
33 changes: 33 additions & 0 deletions pkg/scalers/cpu_memory_scaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@ var validCPUMemoryMetadata = map[string]string{
"type": "Utilization",
"value": "50",
}
var validContainerCPUMemoryMetadata = map[string]string{
"type": "Utilization",
"value": "50",
"containerName": "foo",
}

var testCPUMemoryMetadata = []parseCPUMemoryMetadataTestData{
{"", map[string]string{}, true},
{"", validCPUMemoryMetadata, false},
{"", validContainerCPUMemoryMetadata, false},
{"", map[string]string{"type": "Utilization", "value": "50"}, false},
{v2beta2.UtilizationMetricType, map[string]string{"value": "50"}, false},
{"", map[string]string{"type": "AverageValue", "value": "50"}, false},
Expand Down Expand Up @@ -75,3 +81,30 @@ func TestGetMetricSpecForScaling(t *testing.T) {
assert.Equal(t, metricSpec[0].Resource.Name, v1.ResourceCPU)
assert.Equal(t, metricSpec[0].Resource.Target.Type, v2beta2.UtilizationMetricType)
}

func TestGetContainerMetricSpecForScaling(t *testing.T) {
// Using trigger.metadata.type field for type
config := &ScalerConfig{
TriggerMetadata: validContainerCPUMemoryMetadata,
}
scaler, _ := NewCPUMemoryScaler(v1.ResourceCPU, config)
metricSpec := scaler.GetMetricSpecForScaling(context.Background())

assert.Equal(t, metricSpec[0].Type, v2beta2.ContainerResourceMetricSourceType)
assert.Equal(t, metricSpec[0].ContainerResource.Name, v1.ResourceCPU)
assert.Equal(t, metricSpec[0].ContainerResource.Target.Type, v2beta2.UtilizationMetricType)
assert.Equal(t, metricSpec[0].ContainerResource.Container, validContainerCPUMemoryMetadata["containerName"])

// Using trigger.metricType field for type
config = &ScalerConfig{
TriggerMetadata: map[string]string{"value": "50", "containerName": "bar"},
MetricType: v2beta2.UtilizationMetricType,
}
scaler, _ = NewCPUMemoryScaler(v1.ResourceCPU, config)
metricSpec = scaler.GetMetricSpecForScaling(context.Background())

assert.Equal(t, metricSpec[0].Type, v2beta2.ContainerResourceMetricSourceType)
assert.Equal(t, metricSpec[0].ContainerResource.Name, v1.ResourceCPU)
assert.Equal(t, metricSpec[0].ContainerResource.Target.Type, v2beta2.UtilizationMetricType)
assert.Equal(t, metricSpec[0].ContainerResource.Container, "bar")
}

0 comments on commit acb03ab

Please sign in to comment.