@@ -24,11 +24,13 @@ import (
24
24
v2 "k8s.io/api/autoscaling/v2"
25
25
"k8s.io/apimachinery/pkg/api/resource"
26
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27
+ "k8s.io/client-go/scale"
27
28
"k8s.io/metrics/pkg/apis/external_metrics"
28
29
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
29
30
logf "sigs.k8s.io/controller-runtime/pkg/log"
30
31
31
32
kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
33
+ "github.com/kedacore/keda/v2/pkg/scaling/resolver"
32
34
)
33
35
34
36
var log = logf .Log .WithName ("fallback" )
@@ -51,7 +53,7 @@ func isFallbackEnabled(scaledObject *kedav1alpha1.ScaledObject, metricSpec v2.Me
51
53
return true
52
54
}
53
55
54
- func GetMetricsWithFallback (ctx context.Context , client runtimeclient.Client , metrics []external_metrics.ExternalMetricValue , suppressedError error , metricName string , scaledObject * kedav1alpha1.ScaledObject , metricSpec v2.MetricSpec ) ([]external_metrics.ExternalMetricValue , bool , error ) {
56
+ func GetMetricsWithFallback (ctx context.Context , client runtimeclient.Client , scaleClient scale. ScalesGetter , metrics []external_metrics.ExternalMetricValue , suppressedError error , metricName string , scaledObject * kedav1alpha1.ScaledObject , metricSpec v2.MetricSpec ) ([]external_metrics.ExternalMetricValue , bool , error ) {
55
57
status := scaledObject .Status .DeepCopy ()
56
58
57
59
initHealthStatus (status )
@@ -81,7 +83,16 @@ func GetMetricsWithFallback(ctx context.Context, client runtimeclient.Client, me
81
83
log .Info ("Failed to validate ScaledObject Spec. Please check that parameters are positive integers" , "scaledObject.Namespace" , scaledObject .Namespace , "scaledObject.Name" , scaledObject .Name )
82
84
return nil , false , suppressedError
83
85
case * healthStatus .NumberOfFailures > scaledObject .Spec .Fallback .FailureThreshold :
84
- return doFallback (scaledObject , metricSpec , metricName , suppressedError ), true , nil
86
+ var currentReplicas int32
87
+ var err error
88
+
89
+ if scaledObject .Spec .Fallback .Behavior != kedav1alpha1 .FallbackBehaviorStatic {
90
+ currentReplicas , err = resolver .GetCurrentReplicas (ctx , client , scaleClient , scaledObject )
91
+ if err != nil {
92
+ return nil , false , suppressedError
93
+ }
94
+ }
95
+ return doFallback (scaledObject , metricSpec , metricName , currentReplicas , suppressedError ), true , nil
85
96
default :
86
97
return nil , false , suppressedError
87
98
}
@@ -108,8 +119,34 @@ func HasValidFallback(scaledObject *kedav1alpha1.ScaledObject) bool {
108
119
modifierChecking
109
120
}
110
121
111
- func doFallback (scaledObject * kedav1alpha1.ScaledObject , metricSpec v2.MetricSpec , metricName string , suppressedError error ) []external_metrics.ExternalMetricValue {
112
- replicas := int64 (scaledObject .Spec .Fallback .Replicas )
122
+ func doFallback (scaledObject * kedav1alpha1.ScaledObject , metricSpec v2.MetricSpec , metricName string , currentReplicas int32 , suppressedError error ) []external_metrics.ExternalMetricValue {
123
+ fallbackBehavior := scaledObject .Spec .Fallback .Behavior
124
+ fallbackReplicas := int64 (scaledObject .Spec .Fallback .Replicas )
125
+ var replicas int64
126
+
127
+ switch fallbackBehavior {
128
+ case kedav1alpha1 .FallbackBehaviorStatic :
129
+ replicas = fallbackReplicas
130
+ case kedav1alpha1 .FallbackBehaviorCurrentReplicas :
131
+ replicas = int64 (currentReplicas )
132
+ case kedav1alpha1 .FallbackBehaviorCurrentReplicasIfHigher :
133
+ currentReplicasCount := int64 (currentReplicas )
134
+ if currentReplicasCount > fallbackReplicas {
135
+ replicas = currentReplicasCount
136
+ } else {
137
+ replicas = fallbackReplicas
138
+ }
139
+ case kedav1alpha1 .FallbackBehaviorCurrentReplicasIfLower :
140
+ currentReplicasCount := int64 (currentReplicas )
141
+ if currentReplicasCount < fallbackReplicas {
142
+ replicas = currentReplicasCount
143
+ } else {
144
+ replicas = fallbackReplicas
145
+ }
146
+ default :
147
+ replicas = fallbackReplicas
148
+ }
149
+
113
150
var normalisationValue int64
114
151
if ! scaledObject .IsUsingModifiers () {
115
152
normalisationValue = int64 (metricSpec .External .Target .AverageValue .AsApproximateFloat64 ())
@@ -126,7 +163,13 @@ func doFallback(scaledObject *kedav1alpha1.ScaledObject, metricSpec v2.MetricSpe
126
163
}
127
164
fallbackMetrics := []external_metrics.ExternalMetricValue {metric }
128
165
129
- log .Info ("Suppressing error, falling back to fallback.replicas" , "scaledObject.Namespace" , scaledObject .Namespace , "scaledObject.Name" , scaledObject .Name , "suppressedError" , suppressedError , "fallback.replicas" , replicas )
166
+ log .Info ("Suppressing error, using fallback metrics" ,
167
+ "scaledObject.Namespace" , scaledObject .Namespace ,
168
+ "scaledObject.Name" , scaledObject .Name ,
169
+ "suppressedError" , suppressedError ,
170
+ "fallback.behavior" , fallbackBehavior ,
171
+ "fallback.replicas" , fallbackReplicas ,
172
+ "workload.currentReplicas" , currentReplicas )
130
173
return fallbackMetrics
131
174
}
132
175
0 commit comments