Skip to content

Commit

Permalink
add targetCPUUTilization to HPA
Browse files Browse the repository at this point in the history
  • Loading branch information
moh-osman3 committed Sep 19, 2022
1 parent f40724e commit d2fa170
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 15 deletions.
6 changes: 4 additions & 2 deletions apis/v1alpha1/opentelemetrycollector_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ type OpenTelemetryCollectorSpec struct {
// MaxReplicas sets an upper bound to the autoscaling feature. If MaxReplicas is set autoscaling is enabled.
// +optional
MaxReplicas *int32 `json:"maxReplicas,omitempty"`

// Autoscaler specifies the pod autoscaling configuration to use
// for the OpenTelemetryCollector workload.
//
// +optional
Autoscaler *AutoscalerSpec `json:"autoscaler,omitempty"`

// TargetCPUUtilization sets the target average CPU used across all replicas.
// If average CPU exceeds this value, the HPA will scale up. Defaults to 90 percent.
// +optional
TargetCPUUtilization *int32 `json:"targetCPUUtilization,omitempty"`
// SecurityContext will be set as the container security context.
// +optional
SecurityContext *v1.SecurityContext `json:"securityContext,omitempty"`
Expand Down
10 changes: 10 additions & 0 deletions apis/v1alpha1/opentelemetrycollector_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ func (r *OpenTelemetryCollector) Default() {
if r.Spec.TargetAllocator.Enabled && r.Spec.TargetAllocator.Replicas == nil {
r.Spec.TargetAllocator.Replicas = &one
}

// Set default targetCPUUtilization for autoscaler
if r.Spec.MaxReplicas != nil && r.Spec.TargetCPUUtilization == nil {
defaultCPUTarget := int32(90)
r.Spec.TargetCPUUtilization = &defaultCPUTarget
}
}

// +kubebuilder:webhook:verbs=create;update,path=/validate-opentelemetry-io-v1alpha1-opentelemetrycollector,mutating=false,failurePolicy=fail,groups=opentelemetry.io,resources=opentelemetrycollectors,versions=v1alpha1,name=vopentelemetrycollectorcreateupdate.kb.io,sideEffects=none,admissionReviewVersions=v1
Expand Down Expand Up @@ -141,6 +147,10 @@ func (r *OpenTelemetryCollector) validateCRDSpec() error {
return fmt.Errorf("the OpenTelemetry Spec autoscale configuration is incorrect, scaleUp should be one or more")
}
}
if r.Spec.TargetCPUUtilization != nil && (*r.Spec.TargetCPUUtilization < int32(1) || *r.Spec.TargetCPUUtilization > int32(99)) {
return fmt.Errorf("the OpenTelemetry Spec autoscale configuration is incorrect, targetCPUUtilization should be greater than 0 and less than 100")
}

}

return nil
Expand Down
7 changes: 6 additions & 1 deletion apis/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,12 @@ spec:
service account to use with this instance.
type: string
type: object
targetCPUUtilization:
description: TargetCPUUtilization sets the target average CPU used
across all replicas. If average CPU exceeds this value, the HPA
will scale up. Defaults to 90 percent.
format: int32
type: integer
tolerations:
description: Toleration to schedule OpenTelemetry Collector pods.
This is only relevant to daemonset, statefulset, and deployment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,12 @@ spec:
service account to use with this instance.
type: string
type: object
targetCPUUtilization:
description: TargetCPUUtilization sets the target average CPU used
across all replicas. If average CPU exceeds this value, the HPA
will scale up. Defaults to 90 percent.
format: int32
type: integer
tolerations:
description: Toleration to schedule OpenTelemetry Collector pods.
This is only relevant to daemonset, statefulset, and deployment
Expand Down
9 changes: 9 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,15 @@ OpenTelemetryCollectorSpec defines the desired state of OpenTelemetryCollector.
TargetAllocator indicates a value which determines whether to spawn a target allocation resource or not.<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>targetCPUUtilization</b></td>
<td>integer</td>
<td>
TargetCPUUtilization sets the target average CPU used across all replicas. If average CPU exceeds this value, the HPA will scale up. Defaults to 90 percent.<br/>
<br/>
<i>Format</i>: int32<br/>
</td>
<td>false</td>
</tr><tr>
<td><b><a href="#opentelemetrycollectorspectolerationsindex">tolerations</a></b></td>
<td>[]object</td>
Expand Down
8 changes: 3 additions & 5 deletions pkg/collector/horizontalpodautoscaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,14 @@ import (
"github.com/open-telemetry/opentelemetry-operator/pkg/naming"
)

const defaultCPUTarget int32 = 90

func HorizontalPodAutoscaler(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTelemetryCollector) client.Object {
autoscalingVersion := cfg.AutoscalingVersion()

labels := Labels(otelcol, cfg.LabelsFilter())
labels["app.kubernetes.io/name"] = naming.Collector(otelcol)

annotations := Annotations(otelcol)
cpuTarget := defaultCPUTarget

var result client.Object

objectMeta := metav1.ObjectMeta{
Expand All @@ -54,7 +52,7 @@ func HorizontalPodAutoscaler(cfg config.Config, logger logr.Logger, otelcol v1al
Name: corev1.ResourceCPU,
Target: autoscalingv2beta2.MetricTarget{
Type: autoscalingv2beta2.UtilizationMetricType,
AverageUtilization: &cpuTarget,
AverageUtilization: otelcol.Spec.TargetCPUUtilization,
},
},
}
Expand Down Expand Up @@ -87,7 +85,7 @@ func HorizontalPodAutoscaler(cfg config.Config, logger logr.Logger, otelcol v1al
Name: corev1.ResourceCPU,
Target: autoscalingv2.MetricTarget{
Type: autoscalingv2.UtilizationMetricType,
AverageUtilization: &cpuTarget,
AverageUtilization: otelcol.Spec.TargetCPUUtilization,
},
},
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/collector/horizontalpodautoscaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ func TestHPA(t *testing.T) {

var minReplicas int32 = 3
var maxReplicas int32 = 5
var cpuUtilization int32 = 90

otelcol := v1alpha1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
},
Spec: v1alpha1.OpenTelemetryCollectorSpec{
Replicas: &minReplicas,
MaxReplicas: &maxReplicas,
Replicas: &minReplicas,
MaxReplicas: &maxReplicas,
TargetCPUUtilization: &cpuUtilization,
},
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/collector/reconcile/horizontalpodautoscaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,15 @@ func setAutoscalerSpec(params Params, autoscalingVersion autodetect.AutoscalingV
} else {
updated.(*autoscalingv2beta2.HorizontalPodAutoscaler).Spec.MinReplicas = &one
}
updated.(*autoscalingv2beta2.HorizontalPodAutoscaler).Spec.Metrics[0].Resource.Target.AverageUtilization = params.Instance.Spec.TargetCPUUtilization
} else {
updated.(*autoscalingv2.HorizontalPodAutoscaler).Spec.MaxReplicas = *params.Instance.Spec.MaxReplicas
if params.Instance.Spec.MinReplicas != nil {
updated.(*autoscalingv2.HorizontalPodAutoscaler).Spec.MinReplicas = params.Instance.Spec.MinReplicas
} else {
updated.(*autoscalingv2.HorizontalPodAutoscaler).Spec.MinReplicas = &one
}
updated.(*autoscalingv2.HorizontalPodAutoscaler).Spec.Metrics[0].Resource.Target.AverageUtilization = params.Instance.Spec.TargetCPUUtilization
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/collector/reconcile/horizontalpodautoscaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func paramsWithHPA(autoscalingVersion autodetect.AutoscalingVersion) Params {

minReplicas := int32(3)
maxReplicas := int32(5)
cpuUtilization := int32(90)

mockAutoDetector := &mockAutoDetect{
HPAVersionFunc: func() (autodetect.AutoscalingVersion, error) {
Expand Down Expand Up @@ -144,9 +145,10 @@ func paramsWithHPA(autoscalingVersion autodetect.AutoscalingVersion) Params {
},
NodePort: 0,
}},
Config: string(configYAML),
Replicas: &minReplicas,
MaxReplicas: &maxReplicas,
Config: string(configYAML),
Replicas: &minReplicas,
MaxReplicas: &maxReplicas,
TargetCPUUtilization: &cpuUtilization,
},
},
Scheme: testScheme,
Expand Down
17 changes: 15 additions & 2 deletions tests/e2e/autoscale/00-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ metadata:
name: simplest-collector
status:
readyReplicas: 1

---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
Expand All @@ -16,4 +15,18 @@ spec:
# This is not neccesarily exact. We really just want to wait until this is no longer <unknown>
status:
currentCPUUtilizationPercentage: 20

---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: simplest-set-utilization-collector
spec:
minReplicas: 1
maxReplicas: 2
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
34 changes: 34 additions & 0 deletions tests/e2e/autoscale/00-install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,37 @@ spec:
receivers: [otlp]
processors: []
exporters: [logging]
---
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: simplest-set-utilization
spec:
minReplicas: 1
maxReplicas: 2
targetCPUUtilization: 50
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 5m
memory: 64Mi

config: |
receivers:
otlp:
protocols:
grpc:
http:
processors:
exporters:
logging:
service:
pipelines:
traces:
receivers: [otlp]
processors: []
exporters: [logging]

0 comments on commit d2fa170

Please sign in to comment.