Skip to content

Commit 3da8a76

Browse files
Merge pull request #644 from ingvagabund/release-4.20
WRKLDS-1728: Promote DevKubeVirtRelieveAndMigrate to GA
2 parents d021c9c + edfa447 commit 3da8a76

17 files changed

+121
-85
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ The following profiles are currently provided:
123123
* [`LifecycleAndUtilization`](#LifecycleAndUtilization)
124124
* [`LongLifecycle`](#LongLifecycle)
125125
* [`CompactAndScale`](#compactandscale-techpreview)
126-
* [`DevKubeVirtRelieveAndMigrate`](#devkubevirtrelieveandmigrate)
126+
* [`KubeVirtRelieveAndMigrate`](#kubevirtrelieveandmigrate)
127127
* [`EvictPodsWithPVC`](#EvictPodsWithPVC)
128128
* [`EvictPodsWithLocalStorage`](#EvictPodsWithLocalStorage)
129129

@@ -169,7 +169,7 @@ An under utilized node is any node consuming less than 20% of its available cpu,
169169
This profile enables the [`HighNodeUtilization`](https://github.com/kubernetes-sigs/descheduler/#highnodeutilization) strategy.
170170
In the future, more configuration may be made available through the operator based on user feedback.
171171

172-
### DevKubeVirtRelieveAndMigrate
172+
### KubeVirtRelieveAndMigrate
173173

174174
This profiles seeks to evict pods from high-cost nodes to relieve overall expenses while considering workload migration.
175175
Node cost can include:

manifests/kube-descheduler-operator.crd.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ spec:
4545
description: evictionLimits restrict the number of evictions during
4646
each descheduling run
4747
properties:
48+
node:
49+
description: node restricts the maximum number of evictions per
50+
node
51+
format: int32
52+
type: integer
4853
total:
4954
description: total restricts the maximum number of overall evictions
5055
format: int32
@@ -205,6 +210,7 @@ spec:
205210
- EvictPodsWithPVC
206211
- CompactAndScale
207212
- DevKubeVirtRelieveAndMigrate
213+
- KubeVirtRelieveAndMigrate
208214
type: string
209215
type: array
210216
unsupportedConfigOverrides:

pkg/apis/descheduler/v1/types_descheduler.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ type Namespaces struct {
196196

197197
// DeschedulerProfile allows configuring the enabled strategy profiles for the descheduler
198198
// it allows multiple profiles to be enabled at once, which will have cumulative effects on the cluster.
199-
// +kubebuilder:validation:Enum=AffinityAndTaints;TopologyAndDuplicates;LifecycleAndUtilization;DevPreviewLongLifecycle;LongLifecycle;SoftTopologyAndDuplicates;EvictPodsWithLocalStorage;EvictPodsWithPVC;CompactAndScale;DevKubeVirtRelieveAndMigrate
199+
// +kubebuilder:validation:Enum=AffinityAndTaints;TopologyAndDuplicates;LifecycleAndUtilization;DevPreviewLongLifecycle;LongLifecycle;SoftTopologyAndDuplicates;EvictPodsWithLocalStorage;EvictPodsWithPVC;CompactAndScale;DevKubeVirtRelieveAndMigrate;KubeVirtRelieveAndMigrate
200200
type DeschedulerProfile string
201201

202202
var (
@@ -231,8 +231,12 @@ var (
231231
// CompactAndScale seeks to evict pods to enable the same workload to run on a smaller set of nodes.
232232
CompactAndScale DeschedulerProfile = "CompactAndScale"
233233

234-
// RelieveAndMigrate seeks to evict pods from high-cost nodes to relieve overall expenses while considering workload migration.
235-
RelieveAndMigrate DeschedulerProfile = "DevKubeVirtRelieveAndMigrate"
234+
// KubeVirtRelieveAndMigrate seeks to evict pods from high-cost nodes to relieve overall expenses while considering workload migration.
235+
KubeVirtRelieveAndMigrate DeschedulerProfile = "KubeVirtRelieveAndMigrate"
236+
237+
// DevKubeVirtRelieveAndMigrate seeks to evict pods from high-cost nodes to relieve overall expenses while considering workload migration.
238+
// Deprecated: use KubeVirtRelieveAndMigrate instead
239+
DevKubeVirtRelieveAndMigrate DeschedulerProfile = "DevKubeVirtRelieveAndMigrate"
236240
)
237241

238242
// DeschedulerProfile allows configuring the enabled strategy profiles for the descheduler

pkg/operator/target_config_reconciler.go

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ func getLowNodeUtilizationThresholds(profileCustomizations *deschedulerv1.Profil
914914
return lowThreshold, highThreshold, nil
915915
}
916916

917-
func getRelieveAndMigrateThresholds(profileCustomizations *deschedulerv1.ProfileCustomizations, useDeviationThresholds bool) (deschedulerapi.Percentage, deschedulerapi.Percentage, error) {
917+
func getKubeVirtRelieveAndMigrateThresholds(profileCustomizations *deschedulerv1.ProfileCustomizations, useDeviationThresholds bool) (deschedulerapi.Percentage, deschedulerapi.Percentage, error) {
918918
if profileCustomizations != nil && (profileCustomizations.DevLowNodeUtilizationThresholds != nil || profileCustomizations.DevDeviationThresholds != nil) {
919919
return getLowNodeUtilizationThresholds(profileCustomizations, false)
920920
}
@@ -1046,9 +1046,9 @@ func lifecycleAndUtilizationProfile(profileCustomizations *deschedulerv1.Profile
10461046
return profile, nil
10471047
}
10481048

1049-
func relieveAndMigrateProfile(profileCustomizations *deschedulerv1.ProfileCustomizations, includedNamespaces, excludedNamespaces, protectedNamespaces []string) (*v1alpha2.DeschedulerProfile, error) {
1049+
func kubeVirtRelieveAndMigrateProfile(profileCustomizations *deschedulerv1.ProfileCustomizations, includedNamespaces, excludedNamespaces, protectedNamespaces []string) (*v1alpha2.DeschedulerProfile, error) {
10501050
profile := &v1alpha2.DeschedulerProfile{
1051-
Name: string(deschedulerv1.RelieveAndMigrate),
1051+
Name: string(deschedulerv1.KubeVirtRelieveAndMigrate),
10521052
PluginConfigs: []v1alpha2.PluginConfig{
10531053
{
10541054
Name: nodeutilization.LowNodeUtilizationPluginName,
@@ -1136,7 +1136,7 @@ func relieveAndMigrateProfile(profileCustomizations *deschedulerv1.ProfileCustom
11361136
}
11371137
}
11381138

1139-
lowThreshold, highThreshold, err := getRelieveAndMigrateThresholds(profileCustomizations, args.UseDeviationThresholds)
1139+
lowThreshold, highThreshold, err := getKubeVirtRelieveAndMigrateThresholds(profileCustomizations, args.UseDeviationThresholds)
11401140
if err != nil {
11411141
return nil, err
11421142
}
@@ -1362,24 +1362,24 @@ func (c *TargetConfigReconciler) manageConfigMap(descheduler *deschedulerv1.Kube
13621362
profile, err = longLifecycleProfile(descheduler.Spec.ProfileCustomizations, includedNamespaces, excludedNamespaces, c.protectedNamespaces, ignorePVCPods, evictLocalStoragePods)
13631363
case deschedulerv1.CompactAndScale:
13641364
profile, err = compactAndScaleProfile(descheduler.Spec.ProfileCustomizations, includedNamespaces, excludedNamespaces, ignorePVCPods, evictLocalStoragePods)
1365-
case deschedulerv1.RelieveAndMigrate:
1365+
case deschedulerv1.KubeVirtRelieveAndMigrate, deschedulerv1.DevKubeVirtRelieveAndMigrate:
13661366
kvDeployed, kverr := c.isKubeVirtDeployed()
13671367
if kverr != nil {
13681368
return nil, false, kverr
13691369
}
13701370
if !kvDeployed {
1371-
return nil, true, fmt.Errorf("profile %v can only be used when KubeVirt is properly deployed", deschedulerv1.RelieveAndMigrate)
1371+
return nil, true, fmt.Errorf("profile %v can only be used when KubeVirt is properly deployed", profileName)
13721372
}
13731373
psiEnabled, psierr := c.isPSIenabled()
13741374
if psierr != nil {
13751375
return nil, false, psierr
13761376
}
13771377
if !psiEnabled {
1378-
return nil, true, fmt.Errorf("profile %v can only be used when PSI metrics are enabled for the worker nodes", deschedulerv1.RelieveAndMigrate)
1378+
return nil, true, fmt.Errorf("profile %v can only be used when PSI metrics are enabled for the worker nodes", profileName)
13791379
}
13801380
kubeVirtShedulable := kubeVirtShedulableLabelSelector
13811381
policy.NodeSelector = &kubeVirtShedulable
1382-
profile, err = relieveAndMigrateProfile(descheduler.Spec.ProfileCustomizations, includedNamespaces, excludedNamespaces, c.protectedNamespaces)
1382+
profile, err = kubeVirtRelieveAndMigrateProfile(descheduler.Spec.ProfileCustomizations, includedNamespaces, excludedNamespaces, c.protectedNamespaces)
13831383
default:
13841384
err = fmt.Errorf("Profile %q not recognized", profileName)
13851385
}
@@ -1428,16 +1428,33 @@ func checkProfileConflicts(profiles sets.String, profileName deschedulerv1.Desch
14281428
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.LongLifecycle, deschedulerv1.LifecycleAndUtilization)
14291429
}
14301430

1431-
if profiles.Has(string(deschedulerv1.DevPreviewLongLifecycle)) && profiles.Has(string(deschedulerv1.RelieveAndMigrate)) {
1432-
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.DevPreviewLongLifecycle, deschedulerv1.RelieveAndMigrate)
1431+
// DevKubeVirtRelieveAndMigrate is deprecated in 4.20, remove in 4.22+
1432+
if profiles.Has(string(deschedulerv1.DevPreviewLongLifecycle)) && profiles.Has(string(deschedulerv1.DevKubeVirtRelieveAndMigrate)) {
1433+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.DevPreviewLongLifecycle, deschedulerv1.DevKubeVirtRelieveAndMigrate)
14331434
}
14341435

1435-
if profiles.Has(string(deschedulerv1.LongLifecycle)) && profiles.Has(string(deschedulerv1.RelieveAndMigrate)) {
1436-
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.LongLifecycle, deschedulerv1.RelieveAndMigrate)
1436+
if profiles.Has(string(deschedulerv1.LongLifecycle)) && profiles.Has(string(deschedulerv1.DevKubeVirtRelieveAndMigrate)) {
1437+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.LongLifecycle, deschedulerv1.DevKubeVirtRelieveAndMigrate)
14371438
}
14381439

1439-
if profiles.Has(string(deschedulerv1.LifecycleAndUtilization)) && profiles.Has(string(deschedulerv1.RelieveAndMigrate)) {
1440-
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.LifecycleAndUtilization, deschedulerv1.RelieveAndMigrate)
1440+
if profiles.Has(string(deschedulerv1.LifecycleAndUtilization)) && profiles.Has(string(deschedulerv1.DevKubeVirtRelieveAndMigrate)) {
1441+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.LifecycleAndUtilization, deschedulerv1.DevKubeVirtRelieveAndMigrate)
1442+
}
1443+
1444+
if profiles.Has(string(deschedulerv1.KubeVirtRelieveAndMigrate)) && profiles.Has(string(deschedulerv1.DevKubeVirtRelieveAndMigrate)) {
1445+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.KubeVirtRelieveAndMigrate, deschedulerv1.DevKubeVirtRelieveAndMigrate)
1446+
}
1447+
1448+
if profiles.Has(string(deschedulerv1.DevPreviewLongLifecycle)) && profiles.Has(string(deschedulerv1.KubeVirtRelieveAndMigrate)) {
1449+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.DevPreviewLongLifecycle, deschedulerv1.KubeVirtRelieveAndMigrate)
1450+
}
1451+
1452+
if profiles.Has(string(deschedulerv1.LongLifecycle)) && profiles.Has(string(deschedulerv1.KubeVirtRelieveAndMigrate)) {
1453+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.LongLifecycle, deschedulerv1.KubeVirtRelieveAndMigrate)
1454+
}
1455+
1456+
if profiles.Has(string(deschedulerv1.LifecycleAndUtilization)) && profiles.Has(string(deschedulerv1.KubeVirtRelieveAndMigrate)) {
1457+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.LifecycleAndUtilization, deschedulerv1.KubeVirtRelieveAndMigrate)
14411458
}
14421459

14431460
if profiles.Has(string(deschedulerv1.SoftTopologyAndDuplicates)) && profiles.Has(string(deschedulerv1.TopologyAndDuplicates)) {
@@ -1456,8 +1473,12 @@ func checkProfileConflicts(profiles sets.String, profileName deschedulerv1.Desch
14561473
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.CompactAndScale, deschedulerv1.DevPreviewLongLifecycle)
14571474
}
14581475

1459-
if profiles.Has(string(deschedulerv1.CompactAndScale)) && profiles.Has(string(deschedulerv1.RelieveAndMigrate)) {
1460-
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.CompactAndScale, deschedulerv1.RelieveAndMigrate)
1476+
if profiles.Has(string(deschedulerv1.CompactAndScale)) && profiles.Has(string(deschedulerv1.DevKubeVirtRelieveAndMigrate)) {
1477+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.CompactAndScale, deschedulerv1.DevKubeVirtRelieveAndMigrate)
1478+
}
1479+
1480+
if profiles.Has(string(deschedulerv1.CompactAndScale)) && profiles.Has(string(deschedulerv1.KubeVirtRelieveAndMigrate)) {
1481+
return fmt.Errorf("cannot declare %s and %s profiles simultaneously, ignoring", deschedulerv1.CompactAndScale, deschedulerv1.KubeVirtRelieveAndMigrate)
14611482
}
14621483

14631484
if profiles.Has(string(deschedulerv1.CompactAndScale)) && profiles.Has(string(deschedulerv1.TopologyAndDuplicates)) {
@@ -1529,12 +1550,7 @@ func (c *TargetConfigReconciler) manageDeschedulerDeployment(descheduler *desche
15291550

15301551
featureGates := []string{}
15311552
evictionsInBackgroundEnabled := descheduler.Spec.ProfileCustomizations != nil && descheduler.Spec.ProfileCustomizations.DevEnableEvictionsInBackground
1532-
for _, profile := range descheduler.Spec.Profiles {
1533-
if profile == deschedulerv1.RelieveAndMigrate {
1534-
evictionsInBackgroundEnabled = true
1535-
break
1536-
}
1537-
}
1553+
evictionsInBackgroundEnabled = evictionsInBackgroundEnabled || hasKubeVirtRelieveAndMigrateProfile(descheduler.Spec.Profiles)
15381554
if evictionsInBackgroundEnabled {
15391555
featureGates = append(featureGates, "EvictionsInBackground=true")
15401556
}
@@ -1682,8 +1698,12 @@ func (c *TargetConfigReconciler) isPSIenabled() (bool, error) {
16821698
}
16831699
}
16841700

1701+
func hasKubeVirtRelieveAndMigrateProfile(profiles []deschedulerv1.DeschedulerProfile) bool {
1702+
return slices.Contains(profiles, deschedulerv1.KubeVirtRelieveAndMigrate) || slices.Contains(profiles, deschedulerv1.DevKubeVirtRelieveAndMigrate)
1703+
}
1704+
16851705
func (c *TargetConfigReconciler) isSoftTainterNeeded(descheduler *deschedulerv1.KubeDescheduler) (bool, error) {
1686-
if slices.Contains(descheduler.Spec.Profiles, deschedulerv1.RelieveAndMigrate) {
1706+
if hasKubeVirtRelieveAndMigrateProfile(descheduler.Spec.Profiles) {
16871707
return true, nil
16881708
}
16891709

@@ -1718,7 +1738,7 @@ func (c *TargetConfigReconciler) isSoftTainterNeeded(descheduler *deschedulerv1.
17181738
// or the user is explicitly configuring DevActualUtilizationProfile profile customization
17191739
func (c *TargetConfigReconciler) isPrometheusAsMetricsProviderForProfiles(descheduler *deschedulerv1.KubeDescheduler) bool {
17201740
if descheduler != nil &&
1721-
(slices.Contains(descheduler.Spec.Profiles, deschedulerv1.RelieveAndMigrate) ||
1741+
(hasKubeVirtRelieveAndMigrateProfile(descheduler.Spec.Profiles) ||
17221742
(descheduler.Spec.ProfileCustomizations != nil && descheduler.Spec.ProfileCustomizations.DevActualUtilizationProfile != "")) {
17231743
return true
17241744
}
@@ -1730,7 +1750,7 @@ func (c *TargetConfigReconciler) setEvictionsLimits(descheduler *deschedulerv1.K
17301750
return
17311751
}
17321752

1733-
if slices.Contains(descheduler.Spec.Profiles, deschedulerv1.RelieveAndMigrate) {
1753+
if hasKubeVirtRelieveAndMigrateProfile(descheduler.Spec.Profiles) {
17341754
policy.MaxNoOfPodsToEvictTotal = utilptr.To[uint](uint(defaultKVParallelMigrationsPerCluster))
17351755
policy.MaxNoOfPodsToEvictPerNode = utilptr.To[uint](uint(defaultKVParallelOutboundMigrationsPerNode))
17361756
}

0 commit comments

Comments
 (0)