-
Notifications
You must be signed in to change notification settings - Fork 40k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Always retry connection reset error in webhook #53947
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -27,6 +27,7 @@ import ( | |||||||||||||||||||||||||||||||||
"k8s.io/apimachinery/pkg/runtime/schema" | ||||||||||||||||||||||||||||||||||
"k8s.io/apimachinery/pkg/runtime/serializer" | ||||||||||||||||||||||||||||||||||
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" | ||||||||||||||||||||||||||||||||||
"k8s.io/apimachinery/pkg/util/net" | ||||||||||||||||||||||||||||||||||
"k8s.io/apimachinery/pkg/util/wait" | ||||||||||||||||||||||||||||||||||
"k8s.io/client-go/rest" | ||||||||||||||||||||||||||||||||||
"k8s.io/client-go/tools/clientcmd" | ||||||||||||||||||||||||||||||||||
|
@@ -104,17 +105,14 @@ func WithExponentialBackoff(initialBackoff time.Duration, webhookFn func() error | |||||||||||||||||||||||||||||||||
var err error | ||||||||||||||||||||||||||||||||||
wait.ExponentialBackoff(backoff, func() (bool, error) { | ||||||||||||||||||||||||||||||||||
err = webhookFn() | ||||||||||||||||||||||||||||||||||
// these errors indicate a need to retry an authentication check | ||||||||||||||||||||||||||||||||||
if apierrors.IsServerTimeout(err) || apierrors.IsTimeout(err) || apierrors.IsTooManyRequests(err) { | ||||||||||||||||||||||||||||||||||
// these errors indicate a transient error that should be retried. | ||||||||||||||||||||||||||||||||||
if net.IsConnectionReset(err) || apierrors.IsInternalError(err) || apierrors.IsTimeout(err) || apierrors.IsTooManyRequests(err) { | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. doesn't client-go already turn connection errors into internal server errors? kubernetes/staging/src/k8s.io/client-go/rest/request.go Lines 652 to 667 in 4a6fec7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. client-go only retries on GET calls because it doesn't want to replay non-idempotent calls. this code should not assume all webhook calls are idempotent, either. seems like it would be better to be able to indicate a request is idempotent There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only if it's a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right... this shouldn't assume all webhook calls are idempotent There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Writing audit logs is not an idempotent call, but it's still better to write audit logs twice than loose, esp. considering that audit logs have ids in it, that allow deduplication
Is there really a need to do so? We still cannot guarantee that a request hasn't been processed if e.g. a timeout is returned. Additionally, for all known to me webhooks (auth[nz], audit) I see no benefit in not retrying connection resets There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean, if we really care about a request being idempotent in this case, we shouldn't unconditionally retry e.g. 5XX. However, nobody complained about this code before, so I think it's safe to assume that retrying is more important than idempotence, WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Hmm, that's probably true |
||||||||||||||||||||||||||||||||||
return false, nil | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
// if the error sends the Retry-After header, we respect it as an explicit confirmation we should retry. | ||||||||||||||||||||||||||||||||||
if _, shouldRetry := apierrors.SuggestsClientDelay(err); shouldRetry { | ||||||||||||||||||||||||||||||||||
return false, nil | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
if apierrors.IsInternalError(err) { | ||||||||||||||||||||||||||||||||||
return false, nil | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||||||||||||||
return false, err | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did you remove
IsServerTimeout
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's already checked in
SuggestsClientDelay
. I can return it, if you want the check to be more explicit