Merge pull request #100959 from p0lyn0mial/upstream-delegated-authn-timeout

DelegatingAuthenticationOptions: TokenReview request timeout

Kubernetes-commit: dc2020eb9d59a19952cbdabd3d4f819c6f307899
This commit is contained in:
Kubernetes Publisher 2021-04-14 18:20:09 -07:00
commit 781f4a4107
8 changed files with 43 additions and 25 deletions

2
Godeps/Godeps.json generated
View File

@ -708,7 +708,7 @@
},
{
"ImportPath": "k8s.io/apimachinery",
"Rev": "d23dd757f6df"
"Rev": "f2987aa1dd04"
},
{
"ImportPath": "k8s.io/client-go",

4
go.mod
View File

@ -43,7 +43,7 @@ require (
gopkg.in/square/go-jose.v2 v2.2.2
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.0.0-20210413071831-424177a9741f
k8s.io/apimachinery v0.0.0-20210411071641-d23dd757f6df
k8s.io/apimachinery v0.0.0-20210414154526-f2987aa1dd04
k8s.io/client-go v0.0.0-20210413072113-44bedf8611f1
k8s.io/component-base v0.0.0-20210412032905-a57cc3fac704
k8s.io/klog/v2 v2.8.0
@ -56,7 +56,7 @@ require (
replace (
k8s.io/api => k8s.io/api v0.0.0-20210413071831-424177a9741f
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20210411071641-d23dd757f6df
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20210414154526-f2987aa1dd04
k8s.io/client-go => k8s.io/client-go v0.0.0-20210413072113-44bedf8611f1
k8s.io/component-base => k8s.io/component-base v0.0.0-20210412032905-a57cc3fac704
)

2
go.sum
View File

@ -603,7 +603,7 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.0.0-20210413071831-424177a9741f/go.mod h1:z5rwqWV0tJyUSHTnixRENUOEmBmFXhjwzlXzLBu3Yqg=
k8s.io/apimachinery v0.0.0-20210411071641-d23dd757f6df/go.mod h1:CRK4uy8GKqwLtMa4Gj9i/B2EBjcqOsuvwP2xZJWUwmk=
k8s.io/apimachinery v0.0.0-20210414154526-f2987aa1dd04/go.mod h1:CRK4uy8GKqwLtMa4Gj9i/B2EBjcqOsuvwP2xZJWUwmk=
k8s.io/client-go v0.0.0-20210413072113-44bedf8611f1/go.mod h1:BkiO/A9EBQzrCXhur41t1+JAHGw4IRXUptQWPaZRdFc=
k8s.io/component-base v0.0.0-20210412032905-a57cc3fac704/go.mod h1:zEytEW+Y696JL4g97mo/bP6hzeY26r9zDRw2IFbc7fE=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=

View File

@ -44,6 +44,9 @@ type DelegatingAuthenticatorConfig struct {
// TokenAccessReviewClient is a client to do token review. It can be nil. Then every token is ignored.
TokenAccessReviewClient authenticationclient.TokenReviewInterface
// TokenAccessReviewTimeout specifies a time limit for requests made by the authorization webhook client.
TokenAccessReviewTimeout time.Duration
// WebhookRetryBackoff specifies the backoff parameters for the authentication webhook retry logic.
// This allows us to configure the sleep time at each iteration and the maximum number of retries allowed
// before we fail the webhook call in order to limit the fan out that ensues when the system is degraded.
@ -88,7 +91,7 @@ func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.Secur
if c.WebhookRetryBackoff == nil {
return nil, nil, errors.New("retry backoff parameters for delegating authentication webhook has not been specified")
}
tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient, c.APIAudiences, *c.WebhookRetryBackoff)
tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient, c.APIAudiences, *c.WebhookRetryBackoff, c.TokenAccessReviewTimeout)
if err != nil {
return nil, nil, err
}

View File

@ -195,9 +195,9 @@ type DelegatingAuthenticationOptions struct {
// before we fail the webhook call in order to limit the fan out that ensues when the system is degraded.
WebhookRetryBackoff *wait.Backoff
// ClientTimeout specifies a time limit for requests made by the authorization webhook client.
// TokenRequestTimeout specifies a time limit for requests made by the authorization webhook client.
// The default value is set to 10 seconds.
ClientTimeout time.Duration
TokenRequestTimeout time.Duration
// CustomRoundTripperFn allows for specifying a middleware function for custom HTTP behaviour for the authentication webhook client.
CustomRoundTripperFn transport.WrapperFunc
@ -214,7 +214,7 @@ func NewDelegatingAuthenticationOptions() *DelegatingAuthenticationOptions {
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
},
WebhookRetryBackoff: DefaultAuthWebhookRetryBackoff(),
ClientTimeout: 10 * time.Second,
TokenRequestTimeout: 10 * time.Second,
}
}
@ -223,9 +223,9 @@ func (s *DelegatingAuthenticationOptions) WithCustomRetryBackoff(backoff wait.Ba
s.WebhookRetryBackoff = &backoff
}
// WithClientTimeout sets the given timeout for the authentication webhook client.
func (s *DelegatingAuthenticationOptions) WithClientTimeout(timeout time.Duration) {
s.ClientTimeout = timeout
// WithRequestTimeout sets the given timeout for requests made by the authentication webhook client.
func (s *DelegatingAuthenticationOptions) WithRequestTimeout(timeout time.Duration) {
s.TokenRequestTimeout = timeout
}
// WithCustomRoundTripper allows for specifying a middleware function for custom HTTP behaviour for the authentication webhook client.
@ -282,9 +282,10 @@ func (s *DelegatingAuthenticationOptions) ApplyTo(authenticationInfo *server.Aut
}
cfg := authenticatorfactory.DelegatingAuthenticatorConfig{
Anonymous: true,
CacheTTL: s.CacheTTL,
WebhookRetryBackoff: s.WebhookRetryBackoff,
Anonymous: true,
CacheTTL: s.CacheTTL,
WebhookRetryBackoff: s.WebhookRetryBackoff,
TokenAccessReviewTimeout: s.TokenRequestTimeout,
}
client, err := s.getClient()
@ -427,7 +428,10 @@ 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
// do not set a timeout on the http client, instead use context for cancellation
// if multiple timeouts were set, the request will pick the smaller timeout to be applied, leaving other useless.
//
// see https://github.com/golang/go/blob/a937729c2c2f6950a32bc5cd0f5b88700882f078/src/net/http/client.go#L364
if s.CustomRoundTripperFn != nil {
clientConfig.Wrap(s.CustomRoundTripperFn)
}

View File

@ -52,17 +52,18 @@ type tokenReviewer interface {
}
type WebhookTokenAuthenticator struct {
tokenReview tokenReviewer
retryBackoff wait.Backoff
implicitAuds authenticator.Audiences
tokenReview tokenReviewer
retryBackoff wait.Backoff
implicitAuds authenticator.Audiences
requestTimeout time.Duration
}
// NewFromInterface creates a webhook authenticator using the given tokenReview
// client. It is recommend to wrap this authenticator with the token cache
// authenticator implemented in
// k8s.io/apiserver/pkg/authentication/token/cache.
func NewFromInterface(tokenReview authenticationv1client.TokenReviewInterface, implicitAuds authenticator.Audiences, retryBackoff wait.Backoff) (*WebhookTokenAuthenticator, error) {
return newWithBackoff(tokenReview, retryBackoff, implicitAuds)
func NewFromInterface(tokenReview authenticationv1client.TokenReviewInterface, implicitAuds authenticator.Audiences, retryBackoff wait.Backoff, requestTimeout time.Duration) (*WebhookTokenAuthenticator, error) {
return newWithBackoff(tokenReview, retryBackoff, implicitAuds, requestTimeout)
}
// New creates a new WebhookTokenAuthenticator from the provided kubeconfig
@ -74,12 +75,12 @@ func New(kubeConfigFile string, version string, implicitAuds authenticator.Audie
if err != nil {
return nil, err
}
return newWithBackoff(tokenReview, retryBackoff, implicitAuds)
return newWithBackoff(tokenReview, retryBackoff, implicitAuds, time.Duration(0))
}
// newWithBackoff allows tests to skip the sleep.
func newWithBackoff(tokenReview tokenReviewer, retryBackoff wait.Backoff, implicitAuds authenticator.Audiences) (*WebhookTokenAuthenticator, error) {
return &WebhookTokenAuthenticator{tokenReview, retryBackoff, implicitAuds}, nil
func newWithBackoff(tokenReview tokenReviewer, retryBackoff wait.Backoff, implicitAuds authenticator.Audiences, requestTimeout time.Duration) (*WebhookTokenAuthenticator, error) {
return &WebhookTokenAuthenticator{tokenReview, retryBackoff, implicitAuds, requestTimeout}, nil
}
// AuthenticateToken implements the authenticator.Token interface.
@ -105,7 +106,17 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token
var (
result *authenticationv1.TokenReview
auds authenticator.Audiences
cancel context.CancelFunc
)
// set a hard timeout if it was defined
// if the child has a shorter deadline then it will expire first,
// otherwise if the parent has a shorter deadline then the parent will expire and it will be propagate to the child
if w.requestTimeout > 0 {
ctx, cancel = context.WithTimeout(ctx, w.requestTimeout)
defer cancel()
}
// WithExponentialBackoff will return tokenreview create error (tokenReviewErr) if any.
if err := webhook.WithExponentialBackoff(ctx, w.retryBackoff, func() error {
var tokenReviewErr error

View File

@ -206,7 +206,7 @@ func newV1TokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte,
return nil, err
}
authn, err := newWithBackoff(c, testRetryBackoff, implicitAuds)
authn, err := newWithBackoff(c, testRetryBackoff, implicitAuds, 10*time.Second)
if err != nil {
return nil, err
}

View File

@ -200,7 +200,7 @@ func newV1beta1TokenAuthenticator(serverURL string, clientCert, clientKey, ca []
return nil, err
}
authn, err := newWithBackoff(c, testRetryBackoff, implicitAuds)
authn, err := newWithBackoff(c, testRetryBackoff, implicitAuds, 10*time.Second)
if err != nil {
return nil, err
}