Re-queue worker pods on transient 502/503/504 from the Kubernetes API - #68998
Closed
1fanwang wants to merge 1 commit into
Closed
Re-queue worker pods on transient 502/503/504 from the Kubernetes API#689981fanwang wants to merge 1 commit into
1fanwang wants to merge 1 commit into
Conversation
When KubernetesExecutor fails to create a worker pod, it re-queues the task on an exceeded-quota / stale-version conflict, 500, or 429, but fails the task outright on 502/503/504 — the gateway / unavailable / timeout codes that spike when the API server or an admission webhook is under load. A shutting-down apiserver returns 503 with Retry-After on every graceful roll, so a worker pod CREATE in flight during a rollout currently kills the task. Treat these as transient and re-queue them (bounded by task_publish_max_retries), honoring Retry-After to back the loop off the same way the 429 path does — matching what client-go already does for all 5xx.
1fanwang
requested review from
hussein-awala,
jedcunningham and
jscheffl
as code owners
June 25, 2026 18:53
This was referenced Jun 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Inspired from @jscheffl 's comment #68480 (comment)
When
KubernetesExecutorfails to create a worker pod, it re-queues the task on anexceeded-quota / stale-version conflict,
500, or429, but lets502/503/504fall through and fail the task immediately. Those are exactly the gateway / unavailable /
timeout codes that spike when the API server or an admission webhook is under load. Concretely,
the API server returns
503withRetry-After: 1on every graceful shutdown (rollout, nodedrain, control-plane autoscale — see
apiserverwaitgroup.go), so a worker pod CREATE that isin flight during any apiserver roll currently kills the task outright instead of retrying.
client-goretries all 5xx and honoursRetry-After; the executor does not.What
Add
502/503/504to the transient set, so a task that hits one is re-queued (bounded bytask_publish_max_retries) instead of failed. When the response carriesRetry-After(ashutting-down apiserver always sends it on
503), pause pod creation until then viacreate_pods_after, exactly as the429path already does; other transient 5xx without theheader retry on the next scheduler loop like
500. TheRetry-Afterparse is guarded so amalformed value can't crash the scheduler loop.
This gap was noticed while reviewing #68480 (concurrent pod creation). It is pre-existing on the
current sync path and independent of that change, so it goes as its own PR; the two touch the same
error handler, so whichever lands second will need a trivial rebase.
Tests
test_run_next_exception_requeuegains502/504(re-queue, retry next loop),503 + Retry-After(re-queue, loop backs off), and
503with retries exhausted (fails). Each fails without this change.E2E
Live
kind(real API server, realKubernetesExecutor.sync()), with a proxy injecting503 + Retry-After: 1on the first CREATE per task — identical config (task_publish_max_retries=3),only the fix differs:
retries=3)main)503→ task failed503→ re-queued, retriedRaw — after
Risk
Behaviour change on the default path: a
502/503/504now re-queues instead of failing thetask — bounded by
task_publish_max_retries(default0, i.e. inert unless retries are alreadyenabled). The existing
429/500/ quota / conflict handling is unchanged.