Skip to content

Commit 15ea63c

Browse files
Merge pull request #510 from tiraboschi/rm_profile_defaults
[RelieveAndMigrate] provide defaults for DevDeviationThresholds and DevActualUtilizationProfile
2 parents 1936ece + 5a9c947 commit 15ea63c

11 files changed

+166
-47
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ The profile exposes the following customization:
185185
- `devActualUtilizationProfile`: Enable load-aware descheduling.
186186
- `devDeviationThresholds`: Have the thresholds be based on the average utilization.
187187

188+
By default, this profile will enable load-aware descheduling based on the `PrometheusCPUCombinedProfile` Prometheus query.
189+
By default, the thresholds will be dynamic (based on the distance from the average utilization) and asymmetric (all the nodes below the average will be considered as underutilized to help rebalancing overutilized outliers) tolerating low deviations (10%).
190+
188191
### EvictPodsWithPVC
189192
By default, the operator prevents pods with PVCs from being evicted. Enabling this
190193
profile in combination with any of the above profiles allows pods with PVCs to be

pkg/operator/target_config_reconciler.go

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,26 @@ func getLowNodeUtilizationThresholds(profileCustomizations *deschedulerv1.Profil
881881
return lowThreshold, highThreshold, nil
882882
}
883883

884+
func getRelieveAndMigrateThresholds(profileCustomizations *deschedulerv1.ProfileCustomizations, useDeviationThresholds bool) (deschedulerapi.Percentage, deschedulerapi.Percentage, error) {
885+
if profileCustomizations != nil && (profileCustomizations.DevLowNodeUtilizationThresholds != nil || profileCustomizations.DevDeviationThresholds != nil) {
886+
return getLowNodeUtilizationThresholds(profileCustomizations, false)
887+
}
888+
889+
const defaultAssymetricDeviatonThresholdLow = 0
890+
const defaultAssymetricDeviatonThresholdHigh = 10
891+
const defaultThresholdLow = 20
892+
const defaultThresholdHigh = 50
893+
894+
lowThreshold := deschedulerapi.Percentage(defaultAssymetricDeviatonThresholdLow)
895+
highThreshold := deschedulerapi.Percentage(defaultAssymetricDeviatonThresholdHigh)
896+
if !useDeviationThresholds {
897+
lowThreshold = deschedulerapi.Percentage(defaultThresholdLow)
898+
highThreshold = deschedulerapi.Percentage(defaultThresholdHigh)
899+
}
900+
901+
return lowThreshold, highThreshold, nil
902+
}
903+
884904
func lifecycleAndUtilizationProfile(profileCustomizations *deschedulerv1.ProfileCustomizations, includedNamespaces, excludedNamespaces, protectedNamespaces []string, ignorePVCPods, evictLocalStoragePods bool) (*v1alpha2.DeschedulerProfile, error) {
885905
profile := &v1alpha2.DeschedulerProfile{
886906
Name: string(deschedulerv1.LifecycleAndUtilization),
@@ -1035,17 +1055,33 @@ func relieveAndMigrateProfile(profileCustomizations *deschedulerv1.ProfileCustom
10351055
setExcludedNamespacesForLowNodeUtilizationPlugin(profile.PluginConfigs[0].Args.Object.(*nodeutilization.LowNodeUtilizationArgs), includedNamespaces, excludedNamespaces, protectedNamespaces)
10361056
}
10371057

1038-
lowThreshold, highThreshold, err := getLowNodeUtilizationThresholds(profileCustomizations, false)
1058+
args := profile.PluginConfigs[0].Args.Object.(*nodeutilization.LowNodeUtilizationArgs)
1059+
1060+
// profile defaults
1061+
const defaultActualUtilizationProfile = deschedulerv1.PrometheusCPUCombinedProfile
1062+
args.UseDeviationThresholds = true
1063+
query, err := utilizationProfileToPrometheusQuery(defaultActualUtilizationProfile)
10391064
if err != nil {
10401065
return nil, err
10411066
}
1042-
1043-
resourceNames := []v1.ResourceName{v1.ResourceCPU, v1.ResourceMemory, v1.ResourcePods}
1044-
args := profile.PluginConfigs[0].Args.Object.(*nodeutilization.LowNodeUtilizationArgs)
1067+
args.MetricsUtilization = &nodeutilization.MetricsUtilization{
1068+
Source: deschedulerapi.MetricsSource(v1alpha2.PrometheusMetrics),
1069+
Prometheus: &nodeutilization.Prometheus{
1070+
Query: query,
1071+
},
1072+
}
1073+
resourceNames := []v1.ResourceName{nodeutilization.MetricResource}
10451074

10461075
if profileCustomizations != nil {
10471076
// enable deviation
1048-
args.UseDeviationThresholds = profileCustomizations.DevDeviationThresholds != nil && *profileCustomizations.DevDeviationThresholds != ""
1077+
if profileCustomizations.DevDeviationThresholds != nil && profileCustomizations.DevLowNodeUtilizationThresholds != nil {
1078+
return nil, fmt.Errorf("only one of DevLowNodeUtilizationThresholds and DevDeviationThresholds customizations can be configured simultaneously")
1079+
}
1080+
if profileCustomizations.DevDeviationThresholds != nil {
1081+
args.UseDeviationThresholds = *profileCustomizations.DevDeviationThresholds != ""
1082+
} else if profileCustomizations.DevLowNodeUtilizationThresholds != nil {
1083+
args.UseDeviationThresholds = *profileCustomizations.DevLowNodeUtilizationThresholds == ""
1084+
}
10491085

10501086
if profileCustomizations.DevActualUtilizationProfile != "" {
10511087
query, err := utilizationProfileToPrometheusQuery(profileCustomizations.DevActualUtilizationProfile)
@@ -1066,6 +1102,10 @@ func relieveAndMigrateProfile(profileCustomizations *deschedulerv1.ProfileCustom
10661102
}
10671103
}
10681104

1105+
lowThreshold, highThreshold, err := getRelieveAndMigrateThresholds(profileCustomizations, args.UseDeviationThresholds)
1106+
if err != nil {
1107+
return nil, err
1108+
}
10691109
for _, resourceName := range resourceNames {
10701110
args.Thresholds[resourceName] = lowThreshold
10711111
args.TargetThresholds[resourceName] = highThreshold

pkg/operator/target_config_reconciler_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,33 @@ func TestManageConfigMap(t *testing.T) {
260260
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/lowNodeUtilizationHighConfig.yaml"))},
261261
},
262262
},
263+
{
264+
name: "RelieveAndMigrateWithoutCustomizations",
265+
descheduler: &deschedulerv1.KubeDescheduler{
266+
Spec: deschedulerv1.KubeDeschedulerSpec{
267+
Profiles: []deschedulerv1.DeschedulerProfile{"DevKubeVirtRelieveAndMigrate"},
268+
ProfileCustomizations: nil,
269+
},
270+
},
271+
want: &corev1.ConfigMap{
272+
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
273+
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/relieveAndMigrateDefaults.yaml"))},
274+
},
275+
nodes: []runtime.Object{
276+
&corev1.Node{
277+
ObjectMeta: metav1.ObjectMeta{
278+
Name: "node1",
279+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
280+
},
281+
},
282+
&corev1.Node{
283+
ObjectMeta: metav1.ObjectMeta{
284+
Name: "node2",
285+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
286+
},
287+
},
288+
},
289+
},
263290
{
264291
name: "RelieveAndMigrateLow",
265292
descheduler: &deschedulerv1.KubeDescheduler{
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
apiVersion: descheduler/v1alpha2
2+
kind: DeschedulerPolicy
3+
nodeSelector: kubevirt.io/schedulable=true
4+
profiles:
5+
- name: DevKubeVirtRelieveAndMigrate
6+
pluginConfig:
7+
- args:
8+
evictableNamespaces:
9+
exclude:
10+
- kube-system
11+
- hypershift
12+
- openshift
13+
- openshift-kube-descheduler-operator
14+
- openshift-kube-scheduler
15+
metricsUtilization:
16+
prometheus:
17+
query: descheduler:combined_utilization_and_pressure:avg1m
18+
source: Prometheus
19+
targetThresholds:
20+
MetricResource: 10
21+
thresholds:
22+
MetricResource: 0
23+
useDeviationThresholds: true
24+
name: LowNodeUtilization
25+
- args:
26+
evictLocalStoragePods: true
27+
name: DefaultEvictor
28+
plugins:
29+
balance:
30+
disabled: null
31+
enabled:
32+
- LowNodeUtilization
33+
deschedule:
34+
disabled: null
35+
enabled: null
36+
filter:
37+
disabled: null
38+
enabled:
39+
- DefaultEvictor
40+
preevictionfilter:
41+
disabled: null
42+
enabled: null
43+
presort:
44+
disabled: null
45+
enabled: null
46+
sort:
47+
disabled: null
48+
enabled: null

pkg/operator/testdata/assets/relieveAndMigrateDynamicThresholdsHigh.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ profiles:
1212
- openshift
1313
- openshift-kube-descheduler-operator
1414
- openshift-kube-scheduler
15+
metricsUtilization:
16+
prometheus:
17+
query: descheduler:combined_utilization_and_pressure:avg1m
18+
source: Prometheus
1519
targetThresholds:
16-
cpu: 30
17-
memory: 30
18-
pods: 30
20+
MetricResource: 30
1921
thresholds:
20-
cpu: 30
21-
memory: 30
22-
pods: 30
22+
MetricResource: 30
2323
useDeviationThresholds: true
2424
name: LowNodeUtilization
2525
- args:

pkg/operator/testdata/assets/relieveAndMigrateDynamicThresholdsLow.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ profiles:
1212
- openshift
1313
- openshift-kube-descheduler-operator
1414
- openshift-kube-scheduler
15+
metricsUtilization:
16+
prometheus:
17+
query: descheduler:combined_utilization_and_pressure:avg1m
18+
source: Prometheus
1519
targetThresholds:
16-
cpu: 10
17-
memory: 10
18-
pods: 10
20+
MetricResource: 10
1921
thresholds:
20-
cpu: 10
21-
memory: 10
22-
pods: 10
22+
MetricResource: 10
2323
useDeviationThresholds: true
2424
name: LowNodeUtilization
2525
- args:

pkg/operator/testdata/assets/relieveAndMigrateDynamicThresholdsMedium.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ profiles:
1212
- openshift
1313
- openshift-kube-descheduler-operator
1414
- openshift-kube-scheduler
15+
metricsUtilization:
16+
prometheus:
17+
query: descheduler:combined_utilization_and_pressure:avg1m
18+
source: Prometheus
1519
targetThresholds:
16-
cpu: 20
17-
memory: 20
18-
pods: 20
20+
MetricResource: 20
1921
thresholds:
20-
cpu: 20
21-
memory: 20
22-
pods: 20
22+
MetricResource: 20
2323
useDeviationThresholds: true
2424
name: LowNodeUtilization
2525
- args:

pkg/operator/testdata/assets/relieveAndMigrateHighConfig.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ profiles:
1212
- openshift
1313
- openshift-kube-descheduler-operator
1414
- openshift-kube-scheduler
15+
metricsUtilization:
16+
prometheus:
17+
query: descheduler:combined_utilization_and_pressure:avg1m
18+
source: Prometheus
1519
targetThresholds:
16-
cpu: 70
17-
memory: 70
18-
pods: 70
20+
MetricResource: 70
1921
thresholds:
20-
cpu: 40
21-
memory: 40
22-
pods: 40
22+
MetricResource: 40
2323
name: LowNodeUtilization
2424
- args:
2525
evictLocalStoragePods: true

pkg/operator/testdata/assets/relieveAndMigrateIncludedNamespace.yaml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ profiles:
1212
- openshift
1313
- openshift-kube-descheduler-operator
1414
- openshift-kube-scheduler
15+
metricsUtilization:
16+
prometheus:
17+
query: descheduler:combined_utilization_and_pressure:avg1m
18+
source: Prometheus
1519
targetThresholds:
16-
cpu: 50
17-
memory: 50
18-
pods: 50
20+
MetricResource: 10
1921
thresholds:
20-
cpu: 20
21-
memory: 20
22-
pods: 20
22+
MetricResource: 0
23+
useDeviationThresholds: true
2324
name: LowNodeUtilization
2425
- args:
2526
evictLocalStoragePods: true

pkg/operator/testdata/assets/relieveAndMigrateLowConfig.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ profiles:
1212
- openshift
1313
- openshift-kube-descheduler-operator
1414
- openshift-kube-scheduler
15+
metricsUtilization:
16+
prometheus:
17+
query: descheduler:combined_utilization_and_pressure:avg1m
18+
source: Prometheus
1519
targetThresholds:
16-
cpu: 30
17-
memory: 30
18-
pods: 30
20+
MetricResource: 30
1921
thresholds:
20-
cpu: 10
21-
memory: 10
22-
pods: 10
22+
MetricResource: 10
2323
name: LowNodeUtilization
2424
- args:
2525
evictLocalStoragePods: true

0 commit comments

Comments
 (0)