mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 18:43:34 +00:00
rebase: update kubernetes to 1.28.0 in main
updating kubernetes to 1.28.0 in the main repo. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
b2fdc269c3
commit
ff3e84ad67
9
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/config.go
generated
vendored
9
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/config.go
generated
vendored
@ -24,7 +24,7 @@ import (
|
||||
|
||||
const (
|
||||
minimumSeats = 1
|
||||
maximumSeats = 10
|
||||
maximumSeatsLimit = 10
|
||||
objectsPerSeat = 100.0
|
||||
watchesPerSeat = 10.0
|
||||
enableMutatingWorkEstimator = true
|
||||
@ -39,12 +39,13 @@ type WorkEstimatorConfig struct {
|
||||
|
||||
// MinimumSeats is the minimum number of seats a request must occupy.
|
||||
MinimumSeats uint64 `json:"minimumSeats,omitempty"`
|
||||
// MaximumSeats is the maximum number of seats a request can occupy
|
||||
|
||||
// MaximumSeatsLimit is an upper limit on the max seats a request can occupy.
|
||||
//
|
||||
// NOTE: work_estimate_seats_samples metric uses the value of maximumSeats
|
||||
// as the upper bound, so when we change maximumSeats we should also
|
||||
// update the buckets of the metric.
|
||||
MaximumSeats uint64 `json:"maximumSeats,omitempty"`
|
||||
MaximumSeatsLimit uint64 `json:"maximumSeatsLimit,omitempty"`
|
||||
}
|
||||
|
||||
// ListWorkEstimatorConfig holds work estimator parameters related to list requests.
|
||||
@ -66,7 +67,7 @@ type MutatingWorkEstimatorConfig struct {
|
||||
func DefaultWorkEstimatorConfig() *WorkEstimatorConfig {
|
||||
return &WorkEstimatorConfig{
|
||||
MinimumSeats: minimumSeats,
|
||||
MaximumSeats: maximumSeats,
|
||||
MaximumSeatsLimit: maximumSeatsLimit,
|
||||
ListWorkEstimatorConfig: defaultListWorkEstimatorConfig(),
|
||||
MutatingWorkEstimatorConfig: defaultMutatingWorkEstimatorConfig(),
|
||||
}
|
||||
|
50
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go
generated
vendored
50
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go
generated
vendored
@ -29,10 +29,11 @@ import (
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func newListWorkEstimator(countFn objectCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc {
|
||||
func newListWorkEstimator(countFn objectCountGetterFunc, config *WorkEstimatorConfig, maxSeatsFn maxSeatsFunc) WorkEstimatorFunc {
|
||||
estimator := &listWorkEstimator{
|
||||
config: config,
|
||||
countGetterFn: countFn,
|
||||
maxSeatsFn: maxSeatsFn,
|
||||
}
|
||||
return estimator.estimate
|
||||
}
|
||||
@ -40,14 +41,21 @@ func newListWorkEstimator(countFn objectCountGetterFunc, config *WorkEstimatorCo
|
||||
type listWorkEstimator struct {
|
||||
config *WorkEstimatorConfig
|
||||
countGetterFn objectCountGetterFunc
|
||||
maxSeatsFn maxSeatsFunc
|
||||
}
|
||||
|
||||
func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate {
|
||||
minSeats := e.config.MinimumSeats
|
||||
maxSeats := e.maxSeatsFn(priorityLevelName)
|
||||
if maxSeats == 0 || maxSeats > e.config.MaximumSeatsLimit {
|
||||
maxSeats = e.config.MaximumSeatsLimit
|
||||
}
|
||||
|
||||
requestInfo, ok := apirequest.RequestInfoFrom(r.Context())
|
||||
if !ok {
|
||||
// no RequestInfo should never happen, but to be on the safe side
|
||||
// let's return maximumSeats
|
||||
return WorkEstimate{InitialSeats: e.config.MaximumSeats}
|
||||
return WorkEstimate{InitialSeats: maxSeats}
|
||||
}
|
||||
|
||||
if requestInfo.Name != "" {
|
||||
@ -56,7 +64,7 @@ func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLe
|
||||
// Example of such list requests:
|
||||
// /apis/certificates.k8s.io/v1/certificatesigningrequests?fieldSelector=metadata.name%3Dcsr-xxs4m
|
||||
// /api/v1/namespaces/test/configmaps?fieldSelector=metadata.name%3Dbig-deployment-1&limit=500&resourceVersion=0
|
||||
return WorkEstimate{InitialSeats: e.config.MinimumSeats}
|
||||
return WorkEstimate{InitialSeats: minSeats}
|
||||
}
|
||||
|
||||
query := r.URL.Query()
|
||||
@ -66,9 +74,18 @@ func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLe
|
||||
|
||||
// This request is destined to fail in the validation layer,
|
||||
// return maximumSeats for this request to be consistent.
|
||||
return WorkEstimate{InitialSeats: e.config.MaximumSeats}
|
||||
return WorkEstimate{InitialSeats: maxSeats}
|
||||
}
|
||||
isListFromCache := !shouldListFromStorage(query, &listOptions)
|
||||
|
||||
// For watch requests, we want to adjust the cost only if they explicitly request
|
||||
// sending initial events.
|
||||
if requestInfo.Verb == "watch" {
|
||||
if listOptions.SendInitialEvents == nil || !*listOptions.SendInitialEvents {
|
||||
return WorkEstimate{InitialSeats: e.config.MinimumSeats}
|
||||
}
|
||||
}
|
||||
|
||||
isListFromCache := requestInfo.Verb == "watch" || !shouldListFromStorage(query, &listOptions)
|
||||
|
||||
numStored, err := e.countGetterFn(key(requestInfo))
|
||||
switch {
|
||||
@ -77,7 +94,7 @@ func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLe
|
||||
// be conservative here and allocate maximum seats to this list request.
|
||||
// NOTE: if a CRD is removed, its count will go stale first and then the
|
||||
// pruner will eventually remove the CRD from the cache.
|
||||
return WorkEstimate{InitialSeats: e.config.MaximumSeats}
|
||||
return WorkEstimate{InitialSeats: maxSeats}
|
||||
case err == ObjectCountNotFoundErr:
|
||||
// there are multiple scenarios in which we can see this error:
|
||||
// a. the type is truly unknown, a typo on the caller's part.
|
||||
@ -91,12 +108,12 @@ func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLe
|
||||
// when aggregated API calls are overestimated, we allocate the minimum
|
||||
// possible seats (see #109106 as an example when being more conservative
|
||||
// led to problems).
|
||||
return WorkEstimate{InitialSeats: e.config.MinimumSeats}
|
||||
return WorkEstimate{InitialSeats: minSeats}
|
||||
case err != nil:
|
||||
// we should never be here since Get returns either ObjectCountStaleErr or
|
||||
// ObjectCountNotFoundErr, return maximumSeats to be on the safe side.
|
||||
klog.ErrorS(err, "Unexpected error from object count tracker")
|
||||
return WorkEstimate{InitialSeats: e.config.MaximumSeats}
|
||||
return WorkEstimate{InitialSeats: maxSeats}
|
||||
}
|
||||
|
||||
limit := numStored
|
||||
@ -125,11 +142,11 @@ func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLe
|
||||
seats := uint64(math.Ceil(float64(estimatedObjectsToBeProcessed) / e.config.ObjectsPerSeat))
|
||||
|
||||
// make sure we never return a seat of zero
|
||||
if seats < e.config.MinimumSeats {
|
||||
seats = e.config.MinimumSeats
|
||||
if seats < minSeats {
|
||||
seats = minSeats
|
||||
}
|
||||
if seats > e.config.MaximumSeats {
|
||||
seats = e.config.MaximumSeats
|
||||
if seats > maxSeats {
|
||||
seats = maxSeats
|
||||
}
|
||||
return WorkEstimate{InitialSeats: seats}
|
||||
}
|
||||
@ -149,9 +166,16 @@ func shouldListFromStorage(query url.Values, opts *metav1.ListOptions) bool {
|
||||
resourceVersion := opts.ResourceVersion
|
||||
match := opts.ResourceVersionMatch
|
||||
pagingEnabled := utilfeature.DefaultFeatureGate.Enabled(features.APIListChunking)
|
||||
consistentListFromCacheEnabled := utilfeature.DefaultFeatureGate.Enabled(features.ConsistentListFromCache)
|
||||
|
||||
// Serve consistent reads from storage if ConsistentListFromCache is disabled
|
||||
consistentReadFromStorage := resourceVersion == "" && !consistentListFromCacheEnabled
|
||||
// Watch cache doesn't support continuations, so serve them from etcd.
|
||||
hasContinuation := pagingEnabled && len(opts.Continue) > 0
|
||||
// Serve paginated requests about revision "0" from watch cache to avoid overwhelming etcd.
|
||||
hasLimit := pagingEnabled && opts.Limit > 0 && resourceVersion != "0"
|
||||
// Watch cache only supports ResourceVersionMatchNotOlderThan (default).
|
||||
unsupportedMatch := match != "" && match != metav1.ResourceVersionMatchNotOlderThan
|
||||
|
||||
return resourceVersion == "" || hasContinuation || hasLimit || unsupportedMatch
|
||||
return consistentReadFromStorage || hasContinuation || hasLimit || unsupportedMatch
|
||||
}
|
||||
|
30
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/mutating_work_estimator.go
generated
vendored
30
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/mutating_work_estimator.go
generated
vendored
@ -25,25 +25,33 @@ import (
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/metrics"
|
||||
)
|
||||
|
||||
func newMutatingWorkEstimator(countFn watchCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc {
|
||||
func newMutatingWorkEstimator(countFn watchCountGetterFunc, config *WorkEstimatorConfig, maxSeatsFn maxSeatsFunc) WorkEstimatorFunc {
|
||||
estimator := &mutatingWorkEstimator{
|
||||
config: config,
|
||||
countFn: countFn,
|
||||
config: config,
|
||||
countFn: countFn,
|
||||
maxSeatsFn: maxSeatsFn,
|
||||
}
|
||||
return estimator.estimate
|
||||
}
|
||||
|
||||
type mutatingWorkEstimator struct {
|
||||
config *WorkEstimatorConfig
|
||||
countFn watchCountGetterFunc
|
||||
config *WorkEstimatorConfig
|
||||
countFn watchCountGetterFunc
|
||||
maxSeatsFn maxSeatsFunc
|
||||
}
|
||||
|
||||
func (e *mutatingWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate {
|
||||
minSeats := e.config.MinimumSeats
|
||||
maxSeats := e.maxSeatsFn(priorityLevelName)
|
||||
if maxSeats == 0 || maxSeats > e.config.MaximumSeatsLimit {
|
||||
maxSeats = e.config.MaximumSeatsLimit
|
||||
}
|
||||
|
||||
// TODO(wojtekt): Remove once we tune the algorithm to not fail
|
||||
// scalability tests.
|
||||
if !e.config.Enabled {
|
||||
return WorkEstimate{
|
||||
InitialSeats: 1,
|
||||
InitialSeats: minSeats,
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,15 +60,15 @@ func (e *mutatingWorkEstimator) estimate(r *http.Request, flowSchemaName, priori
|
||||
// no RequestInfo should never happen, but to be on the safe side
|
||||
// let's return a large value.
|
||||
return WorkEstimate{
|
||||
InitialSeats: 1,
|
||||
FinalSeats: e.config.MaximumSeats,
|
||||
InitialSeats: minSeats,
|
||||
FinalSeats: maxSeats,
|
||||
AdditionalLatency: e.config.eventAdditionalDuration(),
|
||||
}
|
||||
}
|
||||
|
||||
if isRequestExemptFromWatchEvents(requestInfo) {
|
||||
return WorkEstimate{
|
||||
InitialSeats: e.config.MinimumSeats,
|
||||
InitialSeats: minSeats,
|
||||
FinalSeats: 0,
|
||||
AdditionalLatency: time.Duration(0),
|
||||
}
|
||||
@ -126,8 +134,8 @@ func (e *mutatingWorkEstimator) estimate(r *http.Request, flowSchemaName, priori
|
||||
//
|
||||
// TODO: Confirm that the current cap of maximumSeats allow us to
|
||||
// achieve the above.
|
||||
if finalSeats > e.config.MaximumSeats {
|
||||
finalSeats = e.config.MaximumSeats
|
||||
if finalSeats > maxSeats {
|
||||
finalSeats = maxSeats
|
||||
}
|
||||
additionalLatency = finalWork.DurationPerSeat(float64(finalSeats))
|
||||
}
|
||||
|
2
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/seat_seconds.go
generated
vendored
2
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/seat_seconds.go
generated
vendored
@ -38,7 +38,7 @@ const MinSeatSeconds = SeatSeconds(0)
|
||||
// This is intended only to produce small values, increments in work
|
||||
// rather than amount of work done since process start.
|
||||
func SeatsTimesDuration(seats float64, duration time.Duration) SeatSeconds {
|
||||
return SeatSeconds(math.Round(seats * float64(duration/time.Nanosecond) / (1e9 / ssScale)))
|
||||
return SeatSeconds(int64(math.Round(seats * float64(duration/time.Nanosecond) / (1e9 / ssScale))))
|
||||
}
|
||||
|
||||
// ToFloat converts to a floating-point representation.
|
||||
|
30
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/width.go
generated
vendored
30
vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/width.go
generated
vendored
@ -22,6 +22,9 @@ import (
|
||||
"time"
|
||||
|
||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
@ -61,15 +64,19 @@ type objectCountGetterFunc func(string) (int64, error)
|
||||
// number of watchers potentially interested in a given request.
|
||||
type watchCountGetterFunc func(*apirequest.RequestInfo) int
|
||||
|
||||
// MaxSeatsFunc represents a function that returns the maximum seats
|
||||
// allowed for the work estimator for a given priority level.
|
||||
type maxSeatsFunc func(priorityLevelName string) uint64
|
||||
|
||||
// NewWorkEstimator estimates the work that will be done by a given request,
|
||||
// if no WorkEstimatorFunc matches the given request then the default
|
||||
// work estimate of 1 seat is allocated to the request.
|
||||
func NewWorkEstimator(objectCountFn objectCountGetterFunc, watchCountFn watchCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc {
|
||||
func NewWorkEstimator(objectCountFn objectCountGetterFunc, watchCountFn watchCountGetterFunc, config *WorkEstimatorConfig, maxSeatsFn maxSeatsFunc) WorkEstimatorFunc {
|
||||
estimator := &workEstimator{
|
||||
minimumSeats: config.MinimumSeats,
|
||||
maximumSeats: config.MaximumSeats,
|
||||
listWorkEstimator: newListWorkEstimator(objectCountFn, config),
|
||||
mutatingWorkEstimator: newMutatingWorkEstimator(watchCountFn, config),
|
||||
maximumSeatsLimit: config.MaximumSeatsLimit,
|
||||
listWorkEstimator: newListWorkEstimator(objectCountFn, config, maxSeatsFn),
|
||||
mutatingWorkEstimator: newMutatingWorkEstimator(watchCountFn, config, maxSeatsFn),
|
||||
}
|
||||
return estimator.estimate
|
||||
}
|
||||
@ -86,8 +93,8 @@ func (e WorkEstimatorFunc) EstimateWork(r *http.Request, flowSchemaName, priorit
|
||||
type workEstimator struct {
|
||||
// the minimum number of seats a request must occupy
|
||||
minimumSeats uint64
|
||||
// the maximum number of seats a request can occupy
|
||||
maximumSeats uint64
|
||||
// the default maximum number of seats a request can occupy
|
||||
maximumSeatsLimit uint64
|
||||
// listWorkEstimator estimates work for list request(s)
|
||||
listWorkEstimator WorkEstimatorFunc
|
||||
// mutatingWorkEstimator calculates the width of mutating request(s)
|
||||
@ -99,12 +106,21 @@ func (e *workEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelN
|
||||
if !ok {
|
||||
klog.ErrorS(fmt.Errorf("no RequestInfo found in context"), "Failed to estimate work for the request", "URI", r.RequestURI)
|
||||
// no RequestInfo should never happen, but to be on the safe side let's return maximumSeats
|
||||
return WorkEstimate{InitialSeats: e.maximumSeats}
|
||||
return WorkEstimate{InitialSeats: e.maximumSeatsLimit}
|
||||
}
|
||||
|
||||
switch requestInfo.Verb {
|
||||
case "list":
|
||||
return e.listWorkEstimator.EstimateWork(r, flowSchemaName, priorityLevelName)
|
||||
case "watch":
|
||||
// WATCH supports `SendInitialEvents` option, which effectively means
|
||||
// that is starts with sending of the contents of a corresponding LIST call.
|
||||
// From that perspective, given that the watch only consumes APF seats
|
||||
// during its initialization (sending init events), its cost should then
|
||||
// be computed the same way as for a regular list.
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.WatchList) {
|
||||
return e.listWorkEstimator.EstimateWork(r, flowSchemaName, priorityLevelName)
|
||||
}
|
||||
case "create", "update", "patch", "delete":
|
||||
return e.mutatingWorkEstimator.EstimateWork(r, flowSchemaName, priorityLevelName)
|
||||
}
|
||||
|
Reference in New Issue
Block a user