diff --git a/go.mod b/go.mod index aceb67f9dd..f370939593 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/openshift/apiserver-library-go v0.0.0-20200424204558-a0c2e02f336f github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc github.com/openshift/client-go v0.0.0-20200521150516-05eb9880269c - github.com/openshift/library-go v0.0.0-20200424095618-2aeb4725dadf + github.com/openshift/library-go v0.0.0-20201209131625-07b0830b8740 github.com/openshift/source-to-image v1.3.1-0.20200213141744-eed2850f2187 github.com/pkg/errors v0.8.1 github.com/sirupsen/logrus v1.4.2 @@ -50,9 +50,9 @@ replace ( k8s.io/api => k8s.io/api v0.18.9 k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.18.9 k8s.io/apimachinery => k8s.io/apimachinery v0.18.9 - k8s.io/apiserver => github.com/openshift/kubernetes-apiserver v0.0.0-20200921103752-4ddb9a66debc + k8s.io/apiserver => github.com/openshift/kubernetes-apiserver v0.0.0-20201209103546-c5587e940bd4 k8s.io/cli-runtime => k8s.io/cli-runtime v0.18.9 - k8s.io/client-go => k8s.io/client-go v0.18.9 + k8s.io/client-go => github.com/openshift/kubernetes-client-go v0.0.0-20201209131240-ad062a7baf0b k8s.io/cloud-provider => k8s.io/cloud-provider v0.18.9 k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.18.9 k8s.io/code-generator => k8s.io/code-generator v0.18.9 diff --git a/go.sum b/go.sum index ac8b9a1689..e01c68d4ae 100644 --- a/go.sum +++ b/go.sum @@ -600,10 +600,14 @@ github.com/openshift/client-go v0.0.0-20200521150516-05eb9880269c h1:l7CmbzzkyWl github.com/openshift/client-go v0.0.0-20200521150516-05eb9880269c/go.mod h1:kCMeo6IE4o4qvnepM9lgHQ4j/ZFfvY/N/2G/jpJdwm4= github.com/openshift/docker-distribution v0.0.0-20180925154709-d4c35485a70d h1:tupVADlF1SZrGy0Y0kg1FKUi2mVPzRwxVb+8LLMu8ws= github.com/openshift/docker-distribution v0.0.0-20180925154709-d4c35485a70d/go.mod h1:XmfFzbwryblvZ29NebonirM7RBuNEO7+yVCOapaouAk= -github.com/openshift/kubernetes-apiserver v0.0.0-20200921103752-4ddb9a66debc h1:0IddNoX6J7AIz7os4pN5HunkFI1g9ARGYsUu1CsvtVg= -github.com/openshift/kubernetes-apiserver v0.0.0-20200921103752-4ddb9a66debc/go.mod h1:vXQzMtUCLsGg1Bh+7Jo2mZKHpHZFCZn8eTNSepcIA1M= +github.com/openshift/kubernetes-apiserver v0.0.0-20201209103546-c5587e940bd4 h1:SEVqzz07YLCtncVyWxGptdrzG3dT3BNdMCRXhAeiwR0= +github.com/openshift/kubernetes-apiserver v0.0.0-20201209103546-c5587e940bd4/go.mod h1:vXQzMtUCLsGg1Bh+7Jo2mZKHpHZFCZn8eTNSepcIA1M= +github.com/openshift/kubernetes-client-go v0.0.0-20201209131240-ad062a7baf0b h1:YD4CN65MUXEMp/g32czgGH9w5aN0cqj+HR/bGoLWfCg= +github.com/openshift/kubernetes-client-go v0.0.0-20201209131240-ad062a7baf0b/go.mod h1:UjkEetDmr40P9NX0Ok3Idt08FCf2I4mIHgjFsot77uY= github.com/openshift/library-go v0.0.0-20200424095618-2aeb4725dadf h1:jUs9QopCnbjbMeOApa7G039n0oHMY2VXm3vu9XLSIhQ= github.com/openshift/library-go v0.0.0-20200424095618-2aeb4725dadf/go.mod h1:2kWwXTkpoQJUN3jZ3QW88EIY1hdRMqxgRs2hheEW/pg= +github.com/openshift/library-go v0.0.0-20201209131625-07b0830b8740 h1:i2j/J5wuy9Rd08xzGjbbIBFYc8I81RQLotdWpr3cZ9o= +github.com/openshift/library-go v0.0.0-20201209131625-07b0830b8740/go.mod h1:lz1w1fHp/mRdMZYJt2khpWudZrb6QP7PmKcBQL6DPmg= github.com/openshift/moby-moby v0.0.0-20190308215630-da810a85109d h1:fLITXDjxMSvUDjnXs/zljIWktbST9+Om8XbrmmM7T4I= github.com/openshift/moby-moby v0.0.0-20190308215630-da810a85109d/go.mod h1:LJM49W8fBVSj+rvcopJZu9mgH5Tx6HwLHySIYeGeu4k= github.com/openshift/source-to-image v1.3.1-0.20200213141744-eed2850f2187 h1:1eVKqhy+oDaHjQ8QJBbmgMRmlXxMi7+D8uXlfVNn4cY= @@ -987,8 +991,6 @@ k8s.io/apimachinery v0.18.9 h1:3ZABKQx3F3xPWlsGhCfUl8W+JXRRblV6Wo2A3zn0pvY= k8s.io/apimachinery v0.18.9/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk= k8s.io/cli-runtime v0.18.9 h1:ko+hFWGCgB3Ue3CPB/525btshO+Sya/D4qNSZ1Nu7J8= k8s.io/cli-runtime v0.18.9/go.mod h1:Pw7UPmZd/wIlGd7DWGTUWA7qn92jCeybNeiS5WYJI6A= -k8s.io/client-go v0.18.9 h1:sPHX49yOtUqv1fl49TwV3f8cC0N3etSnwgFGsIsXnZc= -k8s.io/client-go v0.18.9/go.mod h1:UjkEetDmr40P9NX0Ok3Idt08FCf2I4mIHgjFsot77uY= k8s.io/cloud-provider v0.18.9/go.mod h1:kwlWAqQK2AzQtq8zhXYRgsgia8zJVqdoonzNOUhDE4c= k8s.io/cluster-bootstrap v0.18.9/go.mod h1:1mBaMJ6iQnJ82oGu2FIhMjZHTSxYXVk6b/e/TYBOP+0= k8s.io/code-generator v0.18.9 h1:o/J5cctAlmk8zBqaz9M5JvUZvgkThDcFqebDvxltQiY= diff --git a/vendor/github.com/openshift/library-go/pkg/config/client/client_config.go b/vendor/github.com/openshift/library-go/pkg/config/client/client_config.go index a247311057..e2b90ca531 100644 --- a/vendor/github.com/openshift/library-go/pkg/config/client/client_config.go +++ b/vendor/github.com/openshift/library-go/pkg/config/client/client_config.go @@ -2,14 +2,12 @@ package client import ( "io/ioutil" - "net" - "net/http" - "time" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "net/http" configv1 "github.com/openshift/api/config/v1" + "github.com/openshift/library-go/pkg/network" ) // GetKubeConfigOrInClusterConfig loads in-cluster config if kubeConfigFile is empty or the file if not, @@ -101,10 +99,7 @@ func (c ClientTransportOverrides) DefaultClientTransport(rt http.RoundTripper) h return rt } - transport.DialContext = (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext + transport.DialContext = network.DefaultClientDialContext() // Hold open more internal idle connections transport.MaxIdleConnsPerHost = 100 diff --git a/vendor/github.com/openshift/library-go/pkg/network/dialer.go b/vendor/github.com/openshift/library-go/pkg/network/dialer.go new file mode 100644 index 0000000000..f19be44a3e --- /dev/null +++ b/vendor/github.com/openshift/library-go/pkg/network/dialer.go @@ -0,0 +1,13 @@ +package network + +import ( + "context" + "net" +) + +type DialContext func(ctx context.Context, network, address string) (net.Conn, error) + +// DefaultDialContext returns a DialContext function from a network dialer with default options sets. +func DefaultClientDialContext() DialContext { + return dialerWithDefaultOptions() +} diff --git a/vendor/github.com/openshift/library-go/pkg/network/dialer_linux.go b/vendor/github.com/openshift/library-go/pkg/network/dialer_linux.go new file mode 100644 index 0000000000..b8ff8db85e --- /dev/null +++ b/vendor/github.com/openshift/library-go/pkg/network/dialer_linux.go @@ -0,0 +1,93 @@ +// +build linux + +package network + +import ( + "net" + "os" + "syscall" + "time" + + "golang.org/x/sys/unix" + + utilerrors "k8s.io/apimachinery/pkg/util/errors" +) + +func dialerWithDefaultOptions() DialContext { + nd := &net.Dialer{ + // TCP_USER_TIMEOUT does affect the behaviour of connect() which is controlled by this field so we set it to the same value + Timeout: 25 * time.Second, + // KeepAlive must to be set to a negative value to stop std library from applying the default values + // by doing so we ensure that the options we are interested in won't be overwritten + KeepAlive: time.Duration(-1), + Control: func(network, address string, con syscall.RawConn) error { + var errs []error + err := con.Control(func(fd uintptr) { + optionsErr := setDefaultSocketOptions(int(fd)) + if optionsErr != nil { + errs = append(errs, optionsErr) + } + }) + if err != nil { + errs = append(errs, err) + } + return utilerrors.NewAggregate(errs) + }, + } + return nd.DialContext +} + +// setDefaultSocketOptions sets custom socket options so that we can detect connections to an unhealthy (dead) peer quickly. +// In particular we set TCP_USER_TIMEOUT that specifies the maximum amount of time that transmitted data may remain +// unacknowledged before TCP will forcibly close the connection. +// +// Note +// TCP_USER_TIMEOUT can't be too low because a single dropped packet might drop the entire connection. +// Ideally it should be set to: TCP_KEEPIDLE + TCP_KEEPINTVL * TCP_KEEPCNT +func setDefaultSocketOptions(fd int) error { + // specifies the maximum amount of time in milliseconds that transmitted data may remain + // unacknowledged before TCP will forcibly close the corresponding connection and return ETIMEDOUT to the application + tcpUserTimeoutInMilliSeconds := int(25 * time.Second / time.Millisecond) + + // specifies the interval at which probes are sent in seconds + tcpKeepIntvl := int(roundDuration(5*time.Second, time.Second)) + + // specifies the threshold for sending the first KEEP ALIVE probe in seconds + tcpKeepIdle := int(roundDuration(2*time.Second, time.Second)) + + // enable keep-alive probes + if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { + return wrapSyscallError("setsockopt", err) + } + + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, tcpUserTimeoutInMilliSeconds); err != nil { + return wrapSyscallError("setsockopt", err) + } + + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, tcpKeepIntvl); err != nil { + return wrapSyscallError("setsockopt", err) + } + + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, tcpKeepIdle); err != nil { + return wrapSyscallError("setsockopt", err) + } + return nil +} + +// roundDurationUp rounds d to the next multiple of to. +// +// note that it was copied from the std library +func roundDuration(d time.Duration, to time.Duration) time.Duration { + return (d + to - 1) / to +} + +// wrapSyscallError takes an error and a syscall name. If the error is +// a syscall.Errno, it wraps it in a os.SyscallError using the syscall name. +// +// note that it was copied from the std library +func wrapSyscallError(name string, err error) error { + if _, ok := err.(syscall.Errno); ok { + err = os.NewSyscallError(name, err) + } + return err +} diff --git a/vendor/github.com/openshift/library-go/pkg/network/dialer_others.go b/vendor/github.com/openshift/library-go/pkg/network/dialer_others.go new file mode 100644 index 0000000000..75f0084540 --- /dev/null +++ b/vendor/github.com/openshift/library-go/pkg/network/dialer_others.go @@ -0,0 +1,19 @@ +// +build !linux + +package network + +import ( + "net" + "time" + + "k8s.io/klog" +) + +func dialerWithDefaultOptions() DialContext { + klog.V(2).Info("Creating the default network Dialer (unsupported platform). It may take up to 15 minutes to detect broken connections and establish a new one") + nd := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + } + return nd.DialContext +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go index 6f1a836e34..9b79b74f5a 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go @@ -159,6 +159,17 @@ var ( }, []string{"verb", "group", "version", "resource", "subresource", "scope", "component", "code"}, ) + + // requestAbortsTotal is a number of aborted requests with http.ErrAbortHandler + requestAbortsTotal = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_request_aborts_total", + Help: "Number of requests which apiserver aborted possibly due to a timeout, for each group, version, verb, resource, subresource and scope", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"verb", "group", "version", "resource", "subresource", "scope"}, + ) + kubectlExeRegexp = regexp.MustCompile(`^.*((?i:kubectl\.exe))`) metrics = []resettableCollector{ @@ -172,6 +183,7 @@ var ( WatchEventsSizes, currentInflightRequests, requestTerminationsTotal, + requestAbortsTotal, } // these are the known (e.g. whitelisted/known) content types which we will report for @@ -236,6 +248,22 @@ func UpdateInflightRequestMetrics(nonmutating, mutating int) { currentInflightRequests.WithLabelValues(MutatingKind).Set(float64(mutating)) } +// RecordRequestAbort records that the request was aborted possibly due to a timeout. +func RecordRequestAbort(req *http.Request, requestInfo *request.RequestInfo) { + if requestInfo == nil { + requestInfo = &request.RequestInfo{Verb: req.Method, Path: req.URL.Path} + } + + scope := CleanScope(requestInfo) + reportedVerb := cleanVerb(canonicalVerb(strings.ToUpper(req.Method), scope), req) + resource := requestInfo.Resource + subresource := requestInfo.Subresource + group := requestInfo.APIGroup + version := requestInfo.APIVersion + + requestAbortsTotal.WithLabelValues(reportedVerb, group, version, resource, subresource, scope).Inc() +} + // RecordRequestTermination records that the request was terminated early as part of a resource // preservation or apiserver self-defense mechanism (e.g. timeouts, maxinflight throttling, // proxyHandler errors). RecordRequestTermination should only be called zero or one times diff --git a/vendor/k8s.io/apiserver/pkg/server/config.go b/vendor/k8s.io/apiserver/pkg/server/config.go index 00efd0cc9d..1e301301ee 100644 --- a/vendor/k8s.io/apiserver/pkg/server/config.go +++ b/vendor/k8s.io/apiserver/pkg/server/config.go @@ -688,7 +688,7 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler { handler = genericfilters.WithProbabilisticGoaway(handler, c.GoawayChance) } handler = genericapifilters.WithCacheControl(handler) - handler = genericfilters.WithPanicRecovery(handler) + handler = genericfilters.WithPanicRecovery(handler, c.RequestInfoResolver) return handler } diff --git a/vendor/k8s.io/apiserver/pkg/server/filters/timeout.go b/vendor/k8s.io/apiserver/pkg/server/filters/timeout.go index 9b8d6d4b13..2405bfd1ff 100644 --- a/vendor/k8s.io/apiserver/pkg/server/filters/timeout.go +++ b/vendor/k8s.io/apiserver/pkg/server/filters/timeout.go @@ -33,8 +33,6 @@ import ( apirequest "k8s.io/apiserver/pkg/endpoints/request" ) -var errConnKilled = fmt.Errorf("killing connection/stream because serving request timed out and response had been started") - // WithTimeoutForNonLongRunningRequests times out non-long-running requests after the time given by timeout. func WithTimeoutForNonLongRunningRequests(handler http.Handler, longRunning apirequest.LongRunningRequestCheck, timeout time.Duration) http.Handler { if longRunning == nil { @@ -246,15 +244,17 @@ func (tw *baseTimeoutWriter) timeout(err *apierrors.StatusError) { // no way to timeout the HTTP request at the point. We have to shutdown // the connection for HTTP1 or reset stream for HTTP2. // - // Note from: Brad Fitzpatrick - // if the ServeHTTP goroutine panics, that will do the best possible thing for both - // HTTP/1 and HTTP/2. In HTTP/1, assuming you're replying with at least HTTP/1.1 and - // you've already flushed the headers so it's using HTTP chunking, it'll kill the TCP - // connection immediately without a proper 0-byte EOF chunk, so the peer will recognize - // the response as bogus. In HTTP/2 the server will just RST_STREAM the stream, leaving - // the TCP connection open, but resetting the stream to the peer so it'll have an error, - // like the HTTP/1 case. - panic(errConnKilled) + // Note from the golang's docs: + // If ServeHTTP panics, the server (the caller of ServeHTTP) assumes + // that the effect of the panic was isolated to the active request. + // It recovers the panic, logs a stack trace to the server error log, + // and either closes the network connection or sends an HTTP/2 + // RST_STREAM, depending on the HTTP protocol. To abort a handler so + // the client sees an interrupted response but the server doesn't log + // an error, panic with the value ErrAbortHandler. + // + // We are throwing http.ErrAbortHandler deliberately so that a client is notified and to suppress a not helpful stacktrace in the logs + panic(http.ErrAbortHandler) } } diff --git a/vendor/k8s.io/apiserver/pkg/server/filters/wrap.go b/vendor/k8s.io/apiserver/pkg/server/filters/wrap.go index 96bebdbd60..ca71a40e06 100644 --- a/vendor/k8s.io/apiserver/pkg/server/filters/wrap.go +++ b/vendor/k8s.io/apiserver/pkg/server/filters/wrap.go @@ -17,22 +17,41 @@ limitations under the License. package filters import ( + "fmt" "net/http" - "k8s.io/klog" - "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apiserver/pkg/endpoints/metrics" + "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/server/httplog" + "k8s.io/klog" ) // WithPanicRecovery wraps an http Handler to recover and log panics (except in the special case of http.ErrAbortHandler panics, which suppress logging). -func WithPanicRecovery(handler http.Handler) http.Handler { +func WithPanicRecovery(handler http.Handler, resolver request.RequestInfoResolver) http.Handler { return withPanicRecovery(handler, func(w http.ResponseWriter, req *http.Request, err interface{}) { if err == http.ErrAbortHandler { - // honor the http.ErrAbortHandler sentinel panic value: - // ErrAbortHandler is a sentinel panic value to abort a handler. - // While any panic from ServeHTTP aborts the response to the client, - // panicking with ErrAbortHandler also suppresses logging of a stack trace to the server's error log. + // Honor the http.ErrAbortHandler sentinel panic value + // + // If ServeHTTP panics, the server (the caller of ServeHTTP) assumes + // that the effect of the panic was isolated to the active request. + // It recovers the panic, logs a stack trace to the server error log, + // and either closes the network connection or sends an HTTP/2 + // RST_STREAM, depending on the HTTP protocol. To abort a handler so + // the client sees an interrupted response but the server doesn't log + // an error, panic with the value ErrAbortHandler. + // + // Note that the ReallyCrash variable controls the behaviour of the HandleCrash function + // So it might actually crash, after calling the handlers + if info, err := resolver.NewRequestInfo(req); err != nil { + metrics.RecordRequestAbort(req, nil) + } else { + metrics.RecordRequestAbort(req, info) + } + // This call can have different handlers, but the default chain rate limits. Call it after the metrics are updated + // in case the rate limit delays it. If you outrun the rate for this one timed out requests, something has gone + // seriously wrong with your server, but generally having a logging signal for timeouts is useful. + runtime.HandleError(fmt.Errorf("timeout or abort while handling: %v %q", req.Method, req.URL.Path)) return } http.Error(w, "This request caused apiserver to panic. Look in the logs for details.", http.StatusInternalServerError) diff --git a/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go b/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go index 9c623f6485..ca3fbd9d5e 100644 --- a/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go +++ b/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go @@ -330,7 +330,7 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { }() // close socket after delayed stopCh - err := s.NonBlockingRun(delayedStopCh) + stoppedCh, err := s.NonBlockingRun(delayedStopCh) if err != nil { return err } @@ -345,6 +345,8 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { // wait for the delayed stopCh before closing the handler chain (it rejects everything after Wait has been called). <-delayedStopCh + // wait for stoppedCh that is closed when the graceful termination (server.Shutdown) is finished. + <-stoppedCh // Wait for all requests to finish, which are bounded by the RequestTimeout variable. s.HandlerChainWaitGroup.Wait() @@ -354,7 +356,8 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { // NonBlockingRun spawns the secure http server. An error is // returned if the secure port cannot be listened on. -func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error { +// The returned channel is closed when the (asynchronous) termination is finished. +func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) (<-chan struct{}, error) { // Use an stop channel to allow graceful shutdown without dropping audit events // after http server shutdown. auditStopCh := make(chan struct{}) @@ -363,7 +366,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error { // before http server start serving. Otherwise the Backend.ProcessEvents call might block. if s.AuditBackend != nil { if err := s.AuditBackend.Run(auditStopCh); err != nil { - return fmt.Errorf("failed to run the audit backend: %v", err) + return nil, fmt.Errorf("failed to run the audit backend: %v", err) } } @@ -376,7 +379,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error { if err != nil { close(internalStopCh) close(auditStopCh) - return err + return nil, err } } @@ -399,7 +402,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error { klog.Errorf("Unable to send systemd daemon successful start message: %v\n", err) } - return nil + return stoppedCh, nil } // installAPIResources is a private method for installing the REST storage backing each api groupversionresource diff --git a/vendor/k8s.io/apiserver/pkg/server/options/authentication.go b/vendor/k8s.io/apiserver/pkg/server/options/authentication.go index 96dbfedd85..66f7d306c7 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/authentication.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/authentication.go @@ -177,6 +177,10 @@ type DelegatingAuthenticationOptions struct { // TolerateInClusterLookupFailure indicates failures to look up authentication configuration from the cluster configmap should not be fatal. // Setting this can result in an authenticator that will reject all requests. TolerateInClusterLookupFailure bool + + // ClientTimeout specifies a time limit for requests made by the authorization webhook client. + // The default value is set to 10 seconds. + ClientTimeout time.Duration } func NewDelegatingAuthenticationOptions() *DelegatingAuthenticationOptions { @@ -189,9 +193,15 @@ func NewDelegatingAuthenticationOptions() *DelegatingAuthenticationOptions { GroupHeaders: []string{"x-remote-group"}, ExtraHeaderPrefixes: []string{"x-remote-extra-"}, }, + ClientTimeout: 10 * time.Second, } } +// WithClientTimeout sets the given timeout for the authentication webhook client. +func (s *DelegatingAuthenticationOptions) WithClientTimeout(timeout time.Duration) { + s.ClientTimeout = timeout +} + func (s *DelegatingAuthenticationOptions) Validate() []error { allErrors := []error{} allErrors = append(allErrors, s.RequestHeader.Validate()...) @@ -378,6 +388,7 @@ func (s *DelegatingAuthenticationOptions) getClient() (kubernetes.Interface, err // set high qps/burst limits since this will effectively limit API server responsiveness clientConfig.QPS = 200 clientConfig.Burst = 400 + clientConfig.Timeout = s.ClientTimeout return kubernetes.NewForConfig(clientConfig) } diff --git a/vendor/k8s.io/apiserver/pkg/server/options/authorization.go b/vendor/k8s.io/apiserver/pkg/server/options/authorization.go index 90d53c9aec..263bc14129 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/authorization.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/authorization.go @@ -59,6 +59,10 @@ type DelegatingAuthorizationOptions struct { // AlwaysAllowGroups are groups which are allowed to take any actions. In kube, this is system:masters. AlwaysAllowGroups []string + + // ClientTimeout specifies a time limit for requests made by SubjectAccessReviews client. + // The default value is set to 10 seconds. + ClientTimeout time.Duration } func NewDelegatingAuthorizationOptions() *DelegatingAuthorizationOptions { @@ -66,6 +70,7 @@ func NewDelegatingAuthorizationOptions() *DelegatingAuthorizationOptions { // very low for responsiveness, but high enough to handle storms AllowCacheTTL: 10 * time.Second, DenyCacheTTL: 10 * time.Second, + ClientTimeout: 10 * time.Second, } } @@ -81,6 +86,11 @@ func (s *DelegatingAuthorizationOptions) WithAlwaysAllowPaths(paths ...string) * return s } +// WithClientTimeout sets the given timeout for SAR client used by this authorizer +func (s *DelegatingAuthorizationOptions) WithClientTimeout(timeout time.Duration) { + s.ClientTimeout = timeout +} + func (s *DelegatingAuthorizationOptions) Validate() []error { allErrors := []error{} return allErrors @@ -186,6 +196,7 @@ func (s *DelegatingAuthorizationOptions) getClient() (kubernetes.Interface, erro // set high qps/burst limits since this will effectively limit API server responsiveness clientConfig.QPS = 200 clientConfig.Burst = 400 + clientConfig.Timeout = s.ClientTimeout // make the client use protobuf protoConfig := rest.CopyConfig(clientConfig) diff --git a/vendor/k8s.io/client-go/transport/cache.go b/vendor/k8s.io/client-go/transport/cache.go index 36d6500f58..af66b58236 100644 --- a/vendor/k8s.io/client-go/transport/cache.go +++ b/vendor/k8s.io/client-go/transport/cache.go @@ -18,12 +18,13 @@ package transport import ( "fmt" - "net" "net/http" "strings" "sync" "time" + libgonetwork "github.com/openshift/library-go/pkg/network" + utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/wait" ) @@ -89,10 +90,7 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { dial := config.Dial if dial == nil { - dial = (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext + dial = libgonetwork.DefaultClientDialContext() } // If we use are reloading files, we need to handle certificate rotation properly diff --git a/vendor/modules.txt b/vendor/modules.txt index a6f85d77be..cf20aafa46 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -391,7 +391,7 @@ github.com/openshift/client-go/user/informers/externalversions/internalinterface github.com/openshift/client-go/user/informers/externalversions/user github.com/openshift/client-go/user/informers/externalversions/user/v1 github.com/openshift/client-go/user/listers/user/v1 -# github.com/openshift/library-go v0.0.0-20200424095618-2aeb4725dadf +# github.com/openshift/library-go v0.0.0-20201209131625-07b0830b8740 github.com/openshift/library-go/pkg/apiserver/admission/admissionregistrationtesting github.com/openshift/library-go/pkg/apiserver/admission/admissionrestconfig github.com/openshift/library-go/pkg/apiserver/admission/admissiontimeout @@ -414,6 +414,7 @@ github.com/openshift/library-go/pkg/image/internal/reference github.com/openshift/library-go/pkg/image/reference github.com/openshift/library-go/pkg/image/registryclient github.com/openshift/library-go/pkg/legacyapi/legacygroupification +github.com/openshift/library-go/pkg/network github.com/openshift/library-go/pkg/oauth/oauthserviceaccountclient github.com/openshift/library-go/pkg/quota/clusterquotamapping github.com/openshift/library-go/pkg/quota/quotautil @@ -837,7 +838,7 @@ k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/json k8s.io/apimachinery/third_party/forked/golang/netutil k8s.io/apimachinery/third_party/forked/golang/reflect -# k8s.io/apiserver v0.18.9 => github.com/openshift/kubernetes-apiserver v0.0.0-20200921103752-4ddb9a66debc +# k8s.io/apiserver v0.18.9 => github.com/openshift/kubernetes-apiserver v0.0.0-20201209103546-c5587e940bd4 k8s.io/apiserver/pkg/admission k8s.io/apiserver/pkg/admission/configuration k8s.io/apiserver/pkg/admission/initializer @@ -980,7 +981,7 @@ k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator k8s.io/cli-runtime/pkg/printers k8s.io/cli-runtime/pkg/resource -# k8s.io/client-go v0.18.9 => k8s.io/client-go v0.18.9 +# k8s.io/client-go v0.18.9 => github.com/openshift/kubernetes-client-go v0.0.0-20201209131240-ad062a7baf0b k8s.io/client-go/discovery k8s.io/client-go/discovery/cached k8s.io/client-go/discovery/cached/disk