Skip to content

Commit

Permalink
Merge pull request #52314 from jpbetz/automated-cherry-pick-of-#51415…
Browse files Browse the repository at this point in the history
…-upstream-release-1.6

Automatic merge from submit-queue

Automated cherry pick of #51415 upstream release 1.6

Cherrypick of #51415



**What this PR does / why we need it**:

Backporting to support Kubernetes users with slower internet connections that need the ability to increase this timeout.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note
```
  • Loading branch information
Kubernetes Submit Queue committed Sep 12, 2017
2 parents d8fe9fa + ce881fc commit 4f4e10c
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 11 deletions.
1 change: 1 addition & 0 deletions cmd/kube-apiserver/app/options/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func TestAddFlagsFlag(t *testing.T) {

args := []string{
"--enable-swagger-ui=true",
"--request-timeout=2m",
}
f.Parse(args)
if !s.Features.EnableSwaggerUI {
Expand Down
10 changes: 7 additions & 3 deletions staging/src/k8s.io/apiserver/pkg/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,11 @@ type Config struct {
// RESTOptionsGetter is used to construct RESTStorage types via the generic registry.
RESTOptionsGetter genericregistry.RESTOptionsGetter

// If specified, requests will be allocated a random timeout between this value, and twice this value.
// Note that it is up to the request handlers to ignore or honor this timeout. In seconds.
// If specified, all requests except those which match the LongRunningFunc predicate will timeout
// after this duration.
RequestTimeout time.Duration
// If specified, long running requests such as watch will be allocated a random timeout between this value, and
// twice this value. Note that it is up to the request handlers to ignore or honor this timeout. In seconds.
MinRequestTimeout int
// MaxRequestsInFlight is the maximum number of parallel non-long-running requests. Every further
// request has to wait. Applies only to non-mutating requests.
Expand Down Expand Up @@ -205,6 +208,7 @@ func NewConfig() *Config {
EnableProfiling: true,
MaxRequestsInFlight: 400,
MaxMutatingRequestsInFlight: 200,
RequestTimeout: time.Duration(60) * time.Second,
MinRequestTimeout: 1800,

// Default to treating watch as a long-running operation
Expand Down Expand Up @@ -430,7 +434,7 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) (secure, insec
generic := func(handler http.Handler) http.Handler {
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc)
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc, c.RequestTimeout)
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc)
handler = genericapifilters.WithRequestInfo(handler, NewRequestInfoResolver(c), c.RequestContextMapper)
handler = apirequest.WithRequestContext(handler, c.RequestContextMapper)
Expand Down
12 changes: 5 additions & 7 deletions staging/src/k8s.io/apiserver/pkg/server/filters/timeout.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ import (
apirequest "k8s.io/apiserver/pkg/endpoints/request"
)

const globalTimeout = time.Minute

var errConnKilled = fmt.Errorf("kill connection/stream")

// WithTimeoutForNonLongRunningRequests times out non-long-running requests after the time given by globalTimeout.
func WithTimeoutForNonLongRunningRequests(handler http.Handler, requestContextMapper apirequest.RequestContextMapper, longRunning LongRunningRequestCheck) http.Handler {
// WithTimeoutForNonLongRunningRequests times out non-long-running requests after the time given by timeout.
func WithTimeoutForNonLongRunningRequests(handler http.Handler, requestContextMapper apirequest.RequestContextMapper, longRunning LongRunningRequestCheck, timeout time.Duration) http.Handler {
if longRunning == nil {
return handler
}
Expand All @@ -44,19 +42,19 @@ func WithTimeoutForNonLongRunningRequests(handler http.Handler, requestContextMa
ctx, ok := requestContextMapper.Get(req)
if !ok {
// if this happens, the handler chain isn't setup correctly because there is no context mapper
return time.After(globalTimeout), apierrors.NewInternalError(fmt.Errorf("no context found for request during timeout"))
return time.After(timeout), apierrors.NewInternalError(fmt.Errorf("no context found for request during timeout"))
}

requestInfo, ok := apirequest.RequestInfoFrom(ctx)
if !ok {
// if this happens, the handler chain isn't setup correctly because there is no request info
return time.After(globalTimeout), apierrors.NewInternalError(fmt.Errorf("no request info found for request during timeout"))
return time.After(timeout), apierrors.NewInternalError(fmt.Errorf("no request info found for request during timeout"))
}

if longRunning(req, requestInfo) {
return nil, nil
}
return time.After(globalTimeout), apierrors.NewServerTimeout(schema.GroupResource{Group: requestInfo.APIGroup, Resource: requestInfo.Resource}, requestInfo.Verb, 0)
return time.After(timeout), apierrors.NewServerTimeout(schema.GroupResource{Group: requestInfo.APIGroup, Resource: requestInfo.Resource}, requestInfo.Verb, 0)
}
return WithTimeout(handler, timeoutFunc)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"net"
"strings"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission"
Expand All @@ -42,6 +43,7 @@ type ServerRunOptions struct {
ExternalHost string
MaxRequestsInFlight int
MaxMutatingRequestsInFlight int
RequestTimeout time.Duration
MinRequestTimeout int
TargetRAMMB int
WatchCacheSizes []string
Expand All @@ -54,6 +56,7 @@ func NewServerRunOptions() *ServerRunOptions {
AdmissionControl: "AlwaysAdmit",
MaxRequestsInFlight: defaults.MaxRequestsInFlight,
MaxMutatingRequestsInFlight: defaults.MaxMutatingRequestsInFlight,
RequestTimeout: defaults.RequestTimeout,
MinRequestTimeout: defaults.MinRequestTimeout,
}
}
Expand All @@ -64,6 +67,7 @@ func (s *ServerRunOptions) ApplyTo(c *server.Config) error {
c.ExternalAddress = s.ExternalHost
c.MaxRequestsInFlight = s.MaxRequestsInFlight
c.MaxMutatingRequestsInFlight = s.MaxMutatingRequestsInFlight
c.RequestTimeout = s.RequestTimeout
c.MinRequestTimeout = s.MinRequestTimeout
c.PublicAddress = s.AdvertiseAddress

Expand Down Expand Up @@ -144,6 +148,11 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
"The maximum number of mutating requests in flight at a given time. When the server exceeds this, "+
"it rejects requests. Zero for no limit.")

fs.DurationVar(&s.RequestTimeout, "request-timeout", s.RequestTimeout, ""+
"An optional field indicating the duration a handler must keep a request open before timing "+
"it out. This is the default request timeout for requests but may be overridden by flags such as "+
"--min-request-timeout for specific types of requests.")

fs.IntVar(&s.MinRequestTimeout, "min-request-timeout", s.MinRequestTimeout, ""+
"An optional field indicating the minimum number of seconds a handler must keep "+
"a request open before timing it out. Currently only honored by the watch request "+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func (h *handlerChainConfig) handlerChain(apiHandler http.Handler, c *genericapi

handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc)
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc, c.RequestTimeout)
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc)
handler = genericapifilters.WithRequestInfo(handler, genericapiserver.NewRequestInfoResolver(c), c.RequestContextMapper)
handler = genericapirequest.WithRequestContext(handler, c.RequestContextMapper)
Expand Down

0 comments on commit 4f4e10c

Please sign in to comment.