Drop LogarithmicScaleDown after the feature GA-ed in 1.31

Signed-off-by: Maciej Szulik <soltysh@gmail.com>
This commit is contained in:
Maciej Szulik 2026-04-30 13:47:24 +02:00
parent 85a9fce0f9
commit 3a8fa19cae
No known key found for this signature in database
GPG key ID: F15E55D276FA84C4
7 changed files with 19 additions and 63 deletions

View file

@ -880,18 +880,14 @@ func (s ActivePodsWithRanks) Less(i, j int) bool {
readyTime1 := podReadyTime(s.Pods[i])
readyTime2 := podReadyTime(s.Pods[j])
if !readyTime1.Equal(readyTime2) {
if !utilfeature.DefaultFeatureGate.Enabled(features.LogarithmicScaleDown) {
if s.Now.IsZero() || readyTime1.IsZero() || readyTime2.IsZero() {
return afterOrZero(readyTime1, readyTime2)
} else {
if s.Now.IsZero() || readyTime1.IsZero() || readyTime2.IsZero() {
return afterOrZero(readyTime1, readyTime2)
}
rankDiff := logarithmicRankDiff(*readyTime1, *readyTime2, s.Now)
if rankDiff == 0 {
return s.Pods[i].UID < s.Pods[j].UID
}
return rankDiff < 0
}
rankDiff := logarithmicRankDiff(*readyTime1, *readyTime2, s.Now)
if rankDiff == 0 {
return s.Pods[i].UID < s.Pods[j].UID
}
return rankDiff < 0
}
}
// 7. Pods with containers with higher restart counts < lower restart counts
@ -900,18 +896,14 @@ func (s ActivePodsWithRanks) Less(i, j int) bool {
}
// 8. Empty creation time pods < newer pods < older pods
if !s.Pods[i].CreationTimestamp.Equal(&s.Pods[j].CreationTimestamp) {
if !utilfeature.DefaultFeatureGate.Enabled(features.LogarithmicScaleDown) {
if s.Now.IsZero() || s.Pods[i].CreationTimestamp.IsZero() || s.Pods[j].CreationTimestamp.IsZero() {
return afterOrZero(&s.Pods[i].CreationTimestamp, &s.Pods[j].CreationTimestamp)
} else {
if s.Now.IsZero() || s.Pods[i].CreationTimestamp.IsZero() || s.Pods[j].CreationTimestamp.IsZero() {
return afterOrZero(&s.Pods[i].CreationTimestamp, &s.Pods[j].CreationTimestamp)
}
rankDiff := logarithmicRankDiff(s.Pods[i].CreationTimestamp, s.Pods[j].CreationTimestamp, s.Now)
if rankDiff == 0 {
return s.Pods[i].UID < s.Pods[j].UID
}
return rankDiff < 0
}
rankDiff := logarithmicRankDiff(s.Pods[i].CreationTimestamp, s.Pods[j].CreationTimestamp, s.Now)
if rankDiff == 0 {
return s.Pods[i].UID < s.Pods[j].UID
}
return rankDiff < 0
}
return false
}

View file

@ -831,9 +831,8 @@ func TestSortingActivePodsWithRanks(t *testing.T) {
ready10Hours = pod("ready-10-hours", "", v1.PodRunning, true, 0, 0, then8Hours, then1Month, nil)
)
equalityTests := []struct {
p1 *v1.Pod
p2 *v1.Pod
disableLogarithmicScaleDown bool
p1 *v1.Pod
p2 *v1.Pod
}{
{p1: unscheduledPod},
{p1: scheduledPendingPod},
@ -849,7 +848,6 @@ func TestSortingActivePodsWithRanks(t *testing.T) {
}
for i, test := range equalityTests {
t.Run(fmt.Sprintf("Equality tests %d", i), func(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LogarithmicScaleDown, !test.disableLogarithmicScaleDown)
if test.p2 == nil {
test.p2 = test.p1
}
@ -869,9 +867,8 @@ func TestSortingActivePodsWithRanks(t *testing.T) {
rank int
}
inequalityTests := []struct {
lesser, greater podWithRank
disablePodDeletioncost bool
disableLogarithmicScaleDown bool
lesser, greater podWithRank
disablePodDeletioncost bool
}{
{lesser: podWithRank{unscheduledPod, 1}, greater: podWithRank{scheduledPendingPod, 2}},
{lesser: podWithRank{unscheduledPod, 2}, greater: podWithRank{scheduledPendingPod, 1}},
@ -895,8 +892,7 @@ func TestSortingActivePodsWithRanks(t *testing.T) {
for i, test := range inequalityTests {
t.Run(fmt.Sprintf("Inequality tests %d", i), func(t *testing.T) {
featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{
features.PodDeletionCost: !test.disablePodDeletioncost,
features.LogarithmicScaleDown: !test.disableLogarithmicScaleDown,
features.PodDeletionCost: !test.disablePodDeletioncost,
})
podsWithRanks := ActivePodsWithRanks{

View file

@ -28,8 +28,8 @@ var (
Subsystem: ReplicaSetControllerSubsystem,
Name: "sorting_deletion_age_ratio",
Help: "The ratio of chosen deleted pod's ages to the current youngest pod's age (at the time). Should be <2. " +
"The intent of this metric is to measure the rough efficacy of the LogarithmicScaleDown feature gate's effect on " +
"the sorting (and deletion) of pods when a replicaset scales down. This only considers Ready pods when calculating and reporting.",
"The intent of this metric is to measure the rough efficacy of the sorting (and deletion) of pods when " +
"a replicaset scales down. This only considers Ready pods when calculating and reporting.",
Buckets: metrics.ExponentialBuckets(0.25, 2, 6),
StabilityLevel: metrics.ALPHA,
},

View file

@ -604,11 +604,6 @@ const (
// Relies on UserNamespacesSupport feature, and thus should follow it when setting defaults.
LocalStorageCapacityIsolationFSQuotaMonitoring featuregate.Feature = "LocalStorageCapacityIsolationFSQuotaMonitoring"
// owner: @damemi
//
// Enables scaling down replicas via logarithmic comparison of creation/ready timestamps
LogarithmicScaleDown featuregate.Feature = "LogarithmicScaleDown"
// owner: @sanposhiho
// kep: https://kep.k8s.io/3633
//
@ -1631,12 +1626,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
},
LogarithmicScaleDown: {
{Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta},
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
},
MatchLabelKeysInPodAffinity: {
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
@ -2513,8 +2502,6 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature
LocalStorageCapacityIsolationFSQuotaMonitoring: {},
LogarithmicScaleDown: {},
MatchLabelKeysInPodAffinity: {},
MatchLabelKeysInPodTopologySpread: {},

View file

@ -122,7 +122,6 @@
| KubeletTracing | :ballot_box_with_check:&nbsp;1.27+ | :closed_lock_with_key:&nbsp;1.34+ | 1.251.26 | 1.271.33 | 1.34 | | | [code](https://cs.k8s.io/?q=%5CbKubeletTracing%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbKubeletTracing%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| ListFromCacheSnapshot | :ballot_box_with_check:&nbsp;1.34+ | | 1.33 | 1.34 | | | | [code](https://cs.k8s.io/?q=%5CbListFromCacheSnapshot%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbListFromCacheSnapshot%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| LocalStorageCapacityIsolationFSQuotaMonitoring | | | 1.151.30 | 1.31 | | | | [code](https://cs.k8s.io/?q=%5CbLocalStorageCapacityIsolationFSQuotaMonitoring%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbLocalStorageCapacityIsolationFSQuotaMonitoring%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| LogarithmicScaleDown | :ballot_box_with_check:&nbsp;1.22+ | :closed_lock_with_key:&nbsp;1.31+ | 1.21 | 1.221.30 | 1.31 | | | [code](https://cs.k8s.io/?q=%5CbLogarithmicScaleDown%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbLogarithmicScaleDown%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| ManifestBasedAdmissionControlConfig | | | 1.36 | | | | | [code](https://cs.k8s.io/?q=%5CbManifestBasedAdmissionControlConfig%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbManifestBasedAdmissionControlConfig%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| MatchLabelKeysInPodAffinity | :ballot_box_with_check:&nbsp;1.31+ | :closed_lock_with_key:&nbsp;1.33+ | 1.291.30 | 1.311.32 | 1.33 | | | [code](https://cs.k8s.io/?q=%5CbMatchLabelKeysInPodAffinity%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbMatchLabelKeysInPodAffinity%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| MatchLabelKeysInPodTopologySpread | :ballot_box_with_check:&nbsp;1.27+ | | 1.251.26 | 1.27 | | | | [code](https://cs.k8s.io/?q=%5CbMatchLabelKeysInPodTopologySpread%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbMatchLabelKeysInPodTopologySpread%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |

View file

@ -1111,20 +1111,6 @@
lockToDefault: false
preRelease: Beta
version: "1.31"
- name: LogarithmicScaleDown
versionedSpecs:
- default: false
lockToDefault: false
preRelease: Alpha
version: "1.21"
- default: true
lockToDefault: false
preRelease: Beta
version: "1.22"
- default: true
lockToDefault: true
preRelease: GA
version: "1.31"
- name: LoggingAlphaOptions
versionedSpecs:
- default: false

View file

@ -30,18 +30,15 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers"
clientset "k8s.io/client-go/kubernetes"
typedv1 "k8s.io/client-go/kubernetes/typed/core/v1"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/retry"
featuregatetesting "k8s.io/component-base/featuregate/testing"
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/controller/replication"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/test/integration/framework"
"k8s.io/kubernetes/test/utils/ktesting"
"k8s.io/utils/ptr"
@ -503,7 +500,6 @@ func TestSpecReplicasChange(t *testing.T) {
}
func TestLogarithmicScaleDown(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LogarithmicScaleDown, true)
tCtx, closeFn, rm, informers, c := rmSetup(t)
defer closeFn()
ns := framework.CreateNamespaceOrDie(c, "test-spec-replicas-change", t)