119
vendor/k8s.io/apiserver/pkg/server/config.go
generated
vendored
119
vendor/k8s.io/apiserver/pkg/server/config.go
generated
vendored
@@ -50,9 +50,11 @@ import (
|
||||
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
|
||||
authorizerunion "k8s.io/apiserver/pkg/authorization/union"
|
||||
"k8s.io/apiserver/pkg/endpoints/discovery"
|
||||
"k8s.io/apiserver/pkg/endpoints/filterlatency"
|
||||
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
|
||||
apiopenapi "k8s.io/apiserver/pkg/endpoints/openapi"
|
||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
genericregistry "k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
"k8s.io/apiserver/pkg/server/egressselector"
|
||||
@@ -60,12 +62,15 @@ import (
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
"k8s.io/apiserver/pkg/server/routes"
|
||||
serverstore "k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/apiserver/pkg/storageversion"
|
||||
"k8s.io/apiserver/pkg/util/feature"
|
||||
utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol"
|
||||
"k8s.io/client-go/informers"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/component-base/logs"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/klog/v2"
|
||||
openapicommon "k8s.io/kube-openapi/pkg/common"
|
||||
utilsnet "k8s.io/utils/net"
|
||||
|
||||
// install apis
|
||||
_ "k8s.io/apiserver/pkg/apis/apiserver/install"
|
||||
@@ -107,7 +112,7 @@ type Config struct {
|
||||
// to set values and determine whether its allowed
|
||||
AdmissionControl admission.Interface
|
||||
CorsAllowedOriginList []string
|
||||
|
||||
HSTSDirectives []string
|
||||
// FlowControl, if not nil, gives priority and fairness to request handling
|
||||
FlowControl utilflowcontrol.Interface
|
||||
|
||||
@@ -160,6 +165,8 @@ type Config struct {
|
||||
Serializer runtime.NegotiatedSerializer
|
||||
// OpenAPIConfig will be used in generating OpenAPI spec. This is nil by default. Use DefaultOpenAPIConfig for "working" defaults.
|
||||
OpenAPIConfig *openapicommon.Config
|
||||
// SkipOpenAPIInstallation avoids installing the OpenAPI handler if set to true.
|
||||
SkipOpenAPIInstallation bool
|
||||
|
||||
// RESTOptionsGetter is used to construct RESTStorage types via the generic registry.
|
||||
RESTOptionsGetter genericregistry.RESTOptionsGetter
|
||||
@@ -220,6 +227,12 @@ type Config struct {
|
||||
// EquivalentResourceRegistry provides information about resources equivalent to a given resource,
|
||||
// and the kind associated with a given resource. As resources are installed, they are registered here.
|
||||
EquivalentResourceRegistry runtime.EquivalentResourceRegistry
|
||||
|
||||
// APIServerID is the ID of this API server
|
||||
APIServerID string
|
||||
|
||||
// StorageVersionManager holds the storage versions of the API resources installed by this server.
|
||||
StorageVersionManager storageversion.Manager
|
||||
}
|
||||
|
||||
type RecommendedConfig struct {
|
||||
@@ -272,10 +285,6 @@ type AuthenticationInfo struct {
|
||||
APIAudiences authenticator.Audiences
|
||||
// Authenticator determines which subject is making the request
|
||||
Authenticator authenticator.Request
|
||||
// SupportsBasicAuth indicates that's at least one Authenticator supports basic auth
|
||||
// If this is true, a basic auth challenge is returned on authentication failure
|
||||
// TODO(roberthbailey): Remove once the server no longer supports http basic auth.
|
||||
SupportsBasicAuth bool
|
||||
}
|
||||
|
||||
type AuthorizationInfo struct {
|
||||
@@ -287,6 +296,10 @@ type AuthorizationInfo struct {
|
||||
// NewConfig returns a Config struct with the default values
|
||||
func NewConfig(codecs serializer.CodecFactory) *Config {
|
||||
defaultHealthChecks := []healthz.HealthChecker{healthz.PingHealthz, healthz.LogHealthz}
|
||||
var id string
|
||||
if feature.DefaultFeatureGate.Enabled(features.APIServerIdentity) {
|
||||
id = "kube-apiserver-" + uuid.New().String()
|
||||
}
|
||||
return &Config{
|
||||
Serializer: codecs,
|
||||
BuildHandlerChainFunc: DefaultBuildHandlerChain,
|
||||
@@ -324,7 +337,9 @@ func NewConfig(codecs serializer.CodecFactory) *Config {
|
||||
|
||||
// Default to treating watch as a long-running operation
|
||||
// Generic API servers have no inherent long-running subresources
|
||||
LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(sets.NewString("watch"), sets.NewString()),
|
||||
LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(sets.NewString("watch"), sets.NewString()),
|
||||
APIServerID: id,
|
||||
StorageVersionManager: storageversion.NewDefaultManager(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -518,7 +533,7 @@ func (c *RecommendedConfig) Complete() CompletedConfig {
|
||||
}
|
||||
|
||||
// New creates a new server which logically combines the handling chain with the passed server.
|
||||
// name is used to differentiate for logging. The handler chain in particular can be difficult as it starts delgating.
|
||||
// name is used to differentiate for logging. The handler chain in particular can be difficult as it starts delegating.
|
||||
// delegationTarget may not be nil.
|
||||
func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*GenericAPIServer, error) {
|
||||
if c.Serializer == nil {
|
||||
@@ -558,7 +573,8 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
|
||||
|
||||
listedPathProvider: apiServerHandler,
|
||||
|
||||
openAPIConfig: c.OpenAPIConfig,
|
||||
openAPIConfig: c.OpenAPIConfig,
|
||||
skipOpenAPIInstallation: c.SkipOpenAPIInstallation,
|
||||
|
||||
postStartHooks: map[string]postStartHookEntry{},
|
||||
preShutdownHooks: map[string]preShutdownHookEntry{},
|
||||
@@ -574,6 +590,9 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
|
||||
|
||||
maxRequestBodyBytes: c.MaxRequestBodyBytes,
|
||||
livezClock: clock.RealClock{},
|
||||
|
||||
APIServerID: c.APIServerID,
|
||||
StorageVersionManager: c.StorageVersionManager,
|
||||
}
|
||||
|
||||
for {
|
||||
@@ -615,11 +634,11 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: Once we get rid of /healthz consider changing this to post-start-hook.
|
||||
err = s.addReadyzChecks(healthz.NewInformerSyncHealthz(c.SharedInformerFactory))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// TODO: Once we get rid of /healthz consider changing this to post-start-hook.
|
||||
err := s.AddReadyzChecks(healthz.NewInformerSyncHealthz(c.SharedInformerFactory))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,6 +646,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
|
||||
if s.isPostStartHookRegistered(priorityAndFairnessConfigConsumerHookName) {
|
||||
} else if c.FlowControl != nil {
|
||||
err := s.AddPostStartHook(priorityAndFairnessConfigConsumerHookName, func(context PostStartHookContext) error {
|
||||
go c.FlowControl.MaintainObservations(context.StopCh)
|
||||
go c.FlowControl.Run(context.StopCh)
|
||||
return nil
|
||||
})
|
||||
@@ -638,6 +658,31 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
|
||||
klog.V(3).Infof("Not requested to run hook %s", priorityAndFairnessConfigConsumerHookName)
|
||||
}
|
||||
|
||||
// Add PostStartHooks for maintaining the watermarks for the Priority-and-Fairness and the Max-in-Flight filters.
|
||||
if c.FlowControl != nil {
|
||||
const priorityAndFairnessFilterHookName = "priority-and-fairness-filter"
|
||||
if !s.isPostStartHookRegistered(priorityAndFairnessFilterHookName) {
|
||||
err := s.AddPostStartHook(priorityAndFairnessFilterHookName, func(context PostStartHookContext) error {
|
||||
genericfilters.StartPriorityAndFairnessWatermarkMaintenance(context.StopCh)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const maxInFlightFilterHookName = "max-in-flight-filter"
|
||||
if !s.isPostStartHookRegistered(maxInFlightFilterHookName) {
|
||||
err := s.AddPostStartHook(maxInFlightFilterHookName, func(context PostStartHookContext) error {
|
||||
genericfilters.StartMaxInFlightWatermarkMaintenance(context.StopCh)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, delegateCheck := range delegationTarget.HealthzChecks() {
|
||||
skip := false
|
||||
for _, existingCheck := range c.HealthzChecks {
|
||||
@@ -668,27 +713,60 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func BuildHandlerChainWithStorageVersionPrecondition(apiHandler http.Handler, c *Config) http.Handler {
|
||||
// WithStorageVersionPrecondition needs the WithRequestInfo to run first
|
||||
handler := genericapifilters.WithStorageVersionPrecondition(apiHandler, c.StorageVersionManager, c.Serializer)
|
||||
return DefaultBuildHandlerChain(handler, c)
|
||||
}
|
||||
|
||||
func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
|
||||
handler := genericapifilters.WithAuthorization(apiHandler, c.Authorization.Authorizer, c.Serializer)
|
||||
handler := filterlatency.TrackCompleted(apiHandler)
|
||||
handler = genericapifilters.WithAuthorization(handler, c.Authorization.Authorizer, c.Serializer)
|
||||
handler = filterlatency.TrackStarted(handler, "authorization")
|
||||
|
||||
if c.FlowControl != nil {
|
||||
handler = filterlatency.TrackCompleted(handler)
|
||||
handler = genericfilters.WithPriorityAndFairness(handler, c.LongRunningFunc, c.FlowControl)
|
||||
handler = filterlatency.TrackStarted(handler, "priorityandfairness")
|
||||
} else {
|
||||
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.LongRunningFunc)
|
||||
}
|
||||
|
||||
handler = filterlatency.TrackCompleted(handler)
|
||||
handler = genericapifilters.WithImpersonation(handler, c.Authorization.Authorizer, c.Serializer)
|
||||
handler = filterlatency.TrackStarted(handler, "impersonation")
|
||||
|
||||
handler = filterlatency.TrackCompleted(handler)
|
||||
handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
|
||||
failedHandler := genericapifilters.Unauthorized(c.Serializer, c.Authentication.SupportsBasicAuth)
|
||||
handler = filterlatency.TrackStarted(handler, "audit")
|
||||
|
||||
failedHandler := genericapifilters.Unauthorized(c.Serializer)
|
||||
failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyChecker)
|
||||
|
||||
failedHandler = filterlatency.TrackCompleted(failedHandler)
|
||||
handler = filterlatency.TrackCompleted(handler)
|
||||
handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences)
|
||||
handler = filterlatency.TrackStarted(handler, "authentication")
|
||||
|
||||
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
||||
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc, c.RequestTimeout)
|
||||
|
||||
// WithTimeoutForNonLongRunningRequests will call the rest of the request handling in a go-routine with the
|
||||
// context with deadline. The go-routine can keep running, while the timeout logic will return a timeout to the client.
|
||||
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc)
|
||||
|
||||
handler = genericapifilters.WithRequestDeadline(handler, c.AuditBackend, c.AuditPolicyChecker,
|
||||
c.LongRunningFunc, c.Serializer, c.RequestTimeout)
|
||||
handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup)
|
||||
handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver)
|
||||
if c.SecureServing != nil && !c.SecureServing.DisableHTTP2 && c.GoawayChance > 0 {
|
||||
handler = genericfilters.WithProbabilisticGoaway(handler, c.GoawayChance)
|
||||
}
|
||||
handler = genericapifilters.WithAuditAnnotations(handler, c.AuditBackend, c.AuditPolicyChecker)
|
||||
handler = genericapifilters.WithWarningRecorder(handler)
|
||||
handler = genericapifilters.WithCacheControl(handler)
|
||||
handler = genericfilters.WithPanicRecovery(handler)
|
||||
handler = genericfilters.WithHSTS(handler, c.HSTSDirectives)
|
||||
handler = genericapifilters.WithRequestReceivedTimestamp(handler)
|
||||
handler = genericfilters.WithPanicRecovery(handler, c.RequestInfoResolver)
|
||||
return handler
|
||||
}
|
||||
|
||||
@@ -717,6 +795,9 @@ func installAPI(s *GenericAPIServer, c *Config) {
|
||||
if c.EnableDiscovery {
|
||||
s.Handler.GoRestfulContainer.Add(s.DiscoveryGroupManager.WebService())
|
||||
}
|
||||
if c.FlowControl != nil && feature.DefaultFeatureGate.Enabled(features.APIPriorityAndFairness) {
|
||||
c.FlowControl.Install(s.Handler.NonGoRestfulMux)
|
||||
}
|
||||
}
|
||||
|
||||
func NewRequestInfoResolver(c *Config) *apirequest.RequestInfoFactory {
|
||||
@@ -742,7 +823,7 @@ func (s *SecureServingInfo) HostPort() (string, int, error) {
|
||||
if err != nil {
|
||||
return "", 0, fmt.Errorf("failed to get port from listener address %q: %v", addr, err)
|
||||
}
|
||||
port, err := strconv.Atoi(portStr)
|
||||
port, err := utilsnet.ParsePort(portStr, true)
|
||||
if err != nil {
|
||||
return "", 0, fmt.Errorf("invalid non-numeric port %q", portStr)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user