diff --git a/pkg/features/features.go b/pkg/features/features.go index 9ace595f9..763e8ea50 100644 --- a/pkg/features/features.go +++ b/pkg/features/features.go @@ -60,6 +60,9 @@ const ( // ElasticQuotaIgnoreTerminatingPod ignore the terminating pod. ElasticQuotaIgnoreTerminatingPod featuregate.Feature = "ElasticQuotaIgnoreTerminatingPod" + // ElasticQuotaImmediateIgnoreTerminatingPod ignore the terminating pod immediately. + ElasticQuotaImmediateIgnoreTerminatingPod featuregate.Feature = "ElasticQuotaImmediateIgnoreTerminatingPod" + // ElasticQuotaGuaranteeUsage enable guarantee the quota usage // In some specific scenarios, resources that have been allocated to users are considered // to belong to the users and will not be preempted back. diff --git a/pkg/features/scheduler_features.go b/pkg/features/scheduler_features.go index 708c1ef37..cae4ebfca 100644 --- a/pkg/features/scheduler_features.go +++ b/pkg/features/scheduler_features.go @@ -66,20 +66,21 @@ const ( ) var defaultSchedulerFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ - CompatibleCSIStorageCapacity: {Default: false, PreRelease: featuregate.Alpha}, - DisableCSIStorageCapacityInformer: {Default: false, PreRelease: featuregate.Alpha}, - CompatiblePodDisruptionBudget: {Default: false, PreRelease: featuregate.Alpha}, - DisablePodDisruptionBudgetInformer: {Default: false, PreRelease: featuregate.Alpha}, - ResizePod: {Default: false, PreRelease: featuregate.Alpha}, - MultiQuotaTree: {Default: false, PreRelease: featuregate.Alpha}, - ElasticQuotaIgnorePodOverhead: {Default: false, PreRelease: featuregate.Alpha}, - ElasticQuotaIgnoreTerminatingPod: {Default: false, PreRelease: featuregate.Alpha}, - ElasticQuotaGuaranteeUsage: {Default: false, PreRelease: featuregate.Alpha}, - DisableDefaultQuota: {Default: false, PreRelease: featuregate.Alpha}, - SupportParentQuotaSubmitPod: {Default: false, PreRelease: featuregate.Alpha}, - CSIStorageCapacity: {Default: true, PreRelease: featuregate.GA}, // remove in 1.26 - GenericEphemeralVolume: {Default: true, PreRelease: featuregate.GA}, - PodDisruptionBudget: {Default: true, PreRelease: featuregate.GA}, + CompatibleCSIStorageCapacity: {Default: false, PreRelease: featuregate.Alpha}, + DisableCSIStorageCapacityInformer: {Default: false, PreRelease: featuregate.Alpha}, + CompatiblePodDisruptionBudget: {Default: false, PreRelease: featuregate.Alpha}, + DisablePodDisruptionBudgetInformer: {Default: false, PreRelease: featuregate.Alpha}, + ResizePod: {Default: false, PreRelease: featuregate.Alpha}, + MultiQuotaTree: {Default: false, PreRelease: featuregate.Alpha}, + ElasticQuotaIgnorePodOverhead: {Default: false, PreRelease: featuregate.Alpha}, + ElasticQuotaIgnoreTerminatingPod: {Default: false, PreRelease: featuregate.Alpha}, + ElasticQuotaImmediateIgnoreTerminatingPod: {Default: false, PreRelease: featuregate.Alpha}, + ElasticQuotaGuaranteeUsage: {Default: false, PreRelease: featuregate.Alpha}, + DisableDefaultQuota: {Default: false, PreRelease: featuregate.Alpha}, + SupportParentQuotaSubmitPod: {Default: false, PreRelease: featuregate.Alpha}, + CSIStorageCapacity: {Default: true, PreRelease: featuregate.GA}, // remove in 1.26 + GenericEphemeralVolume: {Default: true, PreRelease: featuregate.GA}, + PodDisruptionBudget: {Default: true, PreRelease: featuregate.GA}, } func init() { diff --git a/pkg/scheduler/plugins/elasticquota/core/group_quota_manager.go b/pkg/scheduler/plugins/elasticquota/core/group_quota_manager.go index 5141be244..c2fcf052f 100644 --- a/pkg/scheduler/plugins/elasticquota/core/group_quota_manager.go +++ b/pkg/scheduler/plugins/elasticquota/core/group_quota_manager.go @@ -1108,6 +1108,10 @@ func shouldBeIgnored(pod *v1.Pod) bool { return false } + if utilfeature.DefaultFeatureGate.Enabled(features.ElasticQuotaImmediateIgnoreTerminatingPod) { + return true + } + if !utilfeature.DefaultFeatureGate.Enabled(features.ElasticQuotaIgnoreTerminatingPod) { return false } diff --git a/pkg/scheduler/plugins/elasticquota/core/group_quota_manager_test.go b/pkg/scheduler/plugins/elasticquota/core/group_quota_manager_test.go index cfbbc7f55..a0a6e488b 100644 --- a/pkg/scheduler/plugins/elasticquota/core/group_quota_manager_test.go +++ b/pkg/scheduler/plugins/elasticquota/core/group_quota_manager_test.go @@ -2067,5 +2067,44 @@ func TestUpdatePod_WhenQuotaCreateAfterPodCreate(t *testing.T) { assert.Equal(t, 1, len(quotaInfo.GetPodCache())) assert.Equal(t, createResourceList(10, 10), quotaInfo.GetRequest()) assert.Equal(t, createResourceList(10, 10), quotaInfo.GetUsed()) +} + +func TestGroupQuotaManager_ImmediateIgnoreTerminatingPod(t *testing.T) { + defer utilfeature.SetFeatureGateDuringTest(t, k8sfeature.DefaultFeatureGate, + features.ElasticQuotaImmediateIgnoreTerminatingPod, true)() + gqm := NewGroupQuotaManagerForTest() + + gqm.UpdateClusterTotalResource(createResourceList(50, 50)) + + qi1 := createQuota("1", extension.RootQuotaName, 40, 40, 10, 10) + gqm.UpdateQuota(qi1, false) + // add pod + pod1 := schetesting.MakePod().Name("1").Obj() + pod1.Spec.Containers = []v1.Container{ + { + Resources: v1.ResourceRequirements{ + Requests: createResourceList(10, 10), + }, + }, + } + pod1.Spec.NodeName = "node1" + gqm.OnPodAdd(qi1.Name, pod1) + assert.Equal(t, createResourceList(10, 10), gqm.GetQuotaInfoByName("1").GetRequest()) + assert.Equal(t, createResourceList(10, 10), gqm.GetQuotaInfoByName("1").GetUsed()) + + // deleting the pod + pod2 := pod1.DeepCopy() + deleteTimestamp := metav1.Time{Time: time.Now()} + deleteGracePeriodsSeconds := int64(30) + pod2.DeletionTimestamp = &deleteTimestamp + pod2.DeletionGracePeriodSeconds = &deleteGracePeriodsSeconds + gqm.OnPodUpdate("1", "1", pod2, pod1) + assert.Equal(t, createResourceList(0, 0), gqm.GetQuotaInfoByName("1").GetRequest()) + assert.Equal(t, createResourceList(0, 0), gqm.GetQuotaInfoByName("1").GetUsed()) + + // delete the pod + gqm.OnPodDelete("1", pod2) + assert.Equal(t, createResourceList(0, 0), gqm.GetQuotaInfoByName("1").GetRequest()) + assert.Equal(t, createResourceList(0, 0), gqm.GetQuotaInfoByName("1").GetUsed()) }