apiserver: allow zero value for the 'nominalConcurrencyShares' field
Kubernetes-commit: 9fd2ab419ad771790d3cb80ea7b8e6828d9ce305
This commit is contained in:
parent
2a3f44cd21
commit
b041969f97
|
@ -23,7 +23,7 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/utils/pointer"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
// The objects that define an apiserver's initial behavior. The
|
||||
|
@ -90,8 +90,8 @@ var (
|
|||
flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementExempt,
|
||||
Exempt: &flowcontrol.ExemptPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: pointer.Int32(0),
|
||||
LendablePercent: pointer.Int32(0),
|
||||
NominalConcurrencyShares: ptr.To(int32(0)),
|
||||
LendablePercent: ptr.To(int32(0)),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -100,8 +100,8 @@ var (
|
|||
flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 5,
|
||||
LendablePercent: pointer.Int32(0),
|
||||
NominalConcurrencyShares: ptr.To(int32(5)),
|
||||
LendablePercent: ptr.To(int32(0)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeReject,
|
||||
},
|
||||
|
@ -173,8 +173,8 @@ var (
|
|||
flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 30,
|
||||
LendablePercent: pointer.Int32(33),
|
||||
NominalConcurrencyShares: ptr.To(int32(30)),
|
||||
LendablePercent: ptr.To(int32(33)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeQueue,
|
||||
Queuing: &flowcontrol.QueuingConfiguration{
|
||||
|
@ -190,8 +190,8 @@ var (
|
|||
flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 40,
|
||||
LendablePercent: pointer.Int32(25),
|
||||
NominalConcurrencyShares: ptr.To(int32(40)),
|
||||
LendablePercent: ptr.To(int32(25)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeQueue,
|
||||
Queuing: &flowcontrol.QueuingConfiguration{
|
||||
|
@ -208,8 +208,8 @@ var (
|
|||
flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 10,
|
||||
LendablePercent: pointer.Int32(0),
|
||||
NominalConcurrencyShares: ptr.To(int32(10)),
|
||||
LendablePercent: ptr.To(int32(0)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeQueue,
|
||||
Queuing: &flowcontrol.QueuingConfiguration{
|
||||
|
@ -226,8 +226,8 @@ var (
|
|||
flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 40,
|
||||
LendablePercent: pointer.Int32(50),
|
||||
NominalConcurrencyShares: ptr.To(int32(40)),
|
||||
LendablePercent: ptr.To(int32(50)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeQueue,
|
||||
Queuing: &flowcontrol.QueuingConfiguration{
|
||||
|
@ -244,8 +244,8 @@ var (
|
|||
flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 100,
|
||||
LendablePercent: pointer.Int32(90),
|
||||
NominalConcurrencyShares: ptr.To(int32(100)),
|
||||
LendablePercent: ptr.To(int32(90)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeQueue,
|
||||
Queuing: &flowcontrol.QueuingConfiguration{
|
||||
|
@ -262,8 +262,8 @@ var (
|
|||
flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 20,
|
||||
LendablePercent: pointer.Int32(50),
|
||||
NominalConcurrencyShares: ptr.To(int32(20)),
|
||||
LendablePercent: ptr.To(int32(50)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeQueue,
|
||||
Queuing: &flowcontrol.QueuingConfiguration{
|
||||
|
|
|
@ -89,7 +89,7 @@ func TestBootstrapPriorityLevelConfigurationWithBorrowing(t *testing.T) {
|
|||
t.Errorf("bootstrap PriorityLevelConfiguration %q is not %q", test.name, flowcontrol.PriorityLevelEnablementLimited)
|
||||
continue
|
||||
}
|
||||
if test.nominalSharesExpected != bootstrapPL.Spec.Limited.NominalConcurrencyShares {
|
||||
if test.nominalSharesExpected != *bootstrapPL.Spec.Limited.NominalConcurrencyShares {
|
||||
t.Errorf("bootstrap PriorityLevelConfiguration %q: expected NominalConcurrencyShares: %d, but got: %d", test.name, test.nominalSharesExpected, bootstrapPL.Spec.Limited.NominalConcurrencyShares)
|
||||
}
|
||||
if test.lendablePercentexpected != *bootstrapPL.Spec.Limited.LendablePercent {
|
||||
|
|
|
@ -251,6 +251,14 @@ const (
|
|||
//
|
||||
// Allow the API server to serve consistent lists from cache
|
||||
ConsistentListFromCache featuregate.Feature = "ConsistentListFromCache"
|
||||
|
||||
// owner: @tkashem
|
||||
// beta: v1.29
|
||||
//
|
||||
// Allow Priority & Fairness in the API server to use a zero value for
|
||||
// the 'nominalConcurrencyShares' field of the 'limited' section of a
|
||||
// priority level.
|
||||
ZeroLimitedNominalConcurrencyShares featuregate.Feature = "ZeroLimitedNominalConcurrencyShares"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -315,4 +323,6 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||
WatchList: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ConsistentListFromCache: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ZeroLimitedNominalConcurrencyShares: {Default: false, PreRelease: featuregate.Beta},
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import (
|
|||
"k8s.io/component-base/metrics/testutil"
|
||||
"k8s.io/klog/v2"
|
||||
clocktesting "k8s.io/utils/clock/testing"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
@ -1307,7 +1308,7 @@ func newConfiguration(fsName, plName, user string, concurrency int32, queueLengt
|
|||
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: concurrency,
|
||||
NominalConcurrencyShares: ptr.To(concurrency),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: responseType,
|
||||
Queuing: qcfg,
|
||||
|
|
|
@ -702,7 +702,7 @@ func (meal *cfgMeal) digestNewPLsLocked(newPLs []*flowcontrol.PriorityLevelConfi
|
|||
state.quiescing = false
|
||||
}
|
||||
nominalConcurrencyShares, _, _ := plSpecCommons(state.pl)
|
||||
meal.shareSum += float64(nominalConcurrencyShares)
|
||||
meal.shareSum += float64(*nominalConcurrencyShares)
|
||||
meal.haveExemptPL = meal.haveExemptPL || pl.Name == flowcontrol.PriorityLevelConfigurationNameExempt
|
||||
meal.haveCatchAllPL = meal.haveCatchAllPL || pl.Name == flowcontrol.PriorityLevelConfigurationNameCatchAll
|
||||
}
|
||||
|
@ -807,7 +807,7 @@ func (meal *cfgMeal) processOldPLsLocked() {
|
|||
// allocation determined by all the share values in the
|
||||
// regular way.
|
||||
nominalConcurrencyShares, _, _ := plSpecCommons(plState.pl)
|
||||
meal.shareSum += float64(nominalConcurrencyShares)
|
||||
meal.shareSum += float64(*nominalConcurrencyShares)
|
||||
meal.haveExemptPL = meal.haveExemptPL || plName == flowcontrol.PriorityLevelConfigurationNameExempt
|
||||
meal.haveCatchAllPL = meal.haveCatchAllPL || plName == flowcontrol.PriorityLevelConfigurationNameCatchAll
|
||||
meal.newPLStates[plName] = plState
|
||||
|
@ -823,7 +823,7 @@ func (meal *cfgMeal) finishQueueSetReconfigsLocked() {
|
|||
// The use of math.Ceil here means that the results might sum
|
||||
// to a little more than serverConcurrencyLimit but the
|
||||
// difference will be negligible.
|
||||
concurrencyLimit := int(math.Ceil(float64(meal.cfgCtlr.serverConcurrencyLimit) * float64(nominalConcurrencyShares) / meal.shareSum))
|
||||
concurrencyLimit := int(math.Ceil(float64(meal.cfgCtlr.serverConcurrencyLimit) * float64(*nominalConcurrencyShares) / meal.shareSum))
|
||||
var lendableCL, borrowingCL int
|
||||
if lendablePercent != nil {
|
||||
lendableCL = int(math.Round(float64(concurrencyLimit) * float64(*lendablePercent) / 100))
|
||||
|
@ -974,7 +974,7 @@ func (meal *cfgMeal) imaginePL(proto *flowcontrol.PriorityLevelConfiguration) {
|
|||
seatDemandRatioedGauge: seatDemandRatioedGauge,
|
||||
}
|
||||
nominalConcurrencyShares, _, _ := plSpecCommons(proto)
|
||||
meal.shareSum += float64(nominalConcurrencyShares)
|
||||
meal.shareSum += float64(*nominalConcurrencyShares)
|
||||
}
|
||||
|
||||
// startRequest classifies and, if appropriate, enqueues the request.
|
||||
|
@ -1112,7 +1112,7 @@ func relDiff(x, y float64) float64 {
|
|||
}
|
||||
|
||||
// plSpecCommons returns the (NominalConcurrencyShares, LendablePercent, BorrowingLimitPercent) of the given priority level config
|
||||
func plSpecCommons(pl *flowcontrol.PriorityLevelConfiguration) (int32, *int32, *int32) {
|
||||
func plSpecCommons(pl *flowcontrol.PriorityLevelConfiguration) (*int32, *int32, *int32) {
|
||||
if limiter := pl.Spec.Limited; limiter != nil {
|
||||
return limiter.NominalConcurrencyShares, limiter.LendablePercent, limiter.BorrowingLimitPercent
|
||||
}
|
||||
|
@ -1121,5 +1121,5 @@ func plSpecCommons(pl *flowcontrol.PriorityLevelConfiguration) (int32, *int32, *
|
|||
if limiter.NominalConcurrencyShares != nil {
|
||||
nominalConcurrencyShares = *limiter.NominalConcurrencyShares
|
||||
}
|
||||
return nominalConcurrencyShares, limiter.LendablePercent, nil
|
||||
return &nominalConcurrencyShares, limiter.LendablePercent, nil
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request"
|
||||
"k8s.io/client-go/informers"
|
||||
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
// TestQueueWaitTimeLatencyTracker tests the queue wait times recorded by the P&F latency tracker
|
||||
|
@ -80,7 +81,7 @@ func TestQueueWaitTimeLatencyTracker(t *testing.T) {
|
|||
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 100,
|
||||
NominalConcurrencyShares: ptr.To(int32(100)),
|
||||
LendablePercent: &lendable,
|
||||
BorrowingLimitPercent: &borrowingLimit,
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request"
|
||||
"k8s.io/client-go/informers"
|
||||
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
type borrowingTestConstraints struct {
|
||||
|
@ -115,7 +116,7 @@ func TestBorrowing(t *testing.T) {
|
|||
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 100,
|
||||
NominalConcurrencyShares: ptr.To(int32(100)),
|
||||
LendablePercent: &testCase.constraints[flow].lendable,
|
||||
BorrowingLimitPercent: &testCase.constraints[flow].borrowing,
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
|
|
|
@ -41,6 +41,7 @@ import (
|
|||
fcclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/clock"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
// Some tests print a lot of debug logs which slows down tests considerably,
|
||||
|
@ -357,7 +358,7 @@ func TestAPFControllerWithGracefulShutdown(t *testing.T) {
|
|||
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 10,
|
||||
NominalConcurrencyShares: ptr.To(int32(10)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeReject,
|
||||
},
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"k8s.io/utils/clock"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
flowcontrol "k8s.io/api/flowcontrol/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -47,7 +48,7 @@ func genPL(rng *rand.Rand, name string) *flowcontrol.PriorityLevelConfiguration
|
|||
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: rng.Int31n(100) + 1,
|
||||
NominalConcurrencyShares: ptr.To(int32(rng.Int31n(100) + 1)),
|
||||
LimitResponse: flowcontrol.LimitResponse{
|
||||
Type: flowcontrol.LimitResponseTypeReject}}}}
|
||||
if rng.Float32() < 0.95 {
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/util/flowcontrol/metrics"
|
||||
"k8s.io/client-go/informers"
|
||||
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
// Test_GetMaxSeats tests max seats retrieved from MaxSeatsTracker
|
||||
|
@ -120,7 +121,7 @@ func Test_GetMaxSeats(t *testing.T) {
|
|||
Spec: flowcontrolv1.PriorityLevelConfigurationSpec{
|
||||
Type: flowcontrolv1.PriorityLevelEnablementLimited,
|
||||
Limited: &flowcontrolv1.LimitedPriorityLevelConfiguration{
|
||||
NominalConcurrencyShares: 10000,
|
||||
NominalConcurrencyShares: ptr.To(int32(10000)),
|
||||
LimitResponse: flowcontrolv1.LimitResponse{
|
||||
Queuing: &flowcontrolv1.QueuingConfiguration{
|
||||
HandSize: testcase.handSize,
|
||||
|
|
Loading…
Reference in New Issue