Repository navigation
fix: skip warm pool sandboxes without a backing pod - #683
kubernetes-prow[bot] merged 10 commits into
Conversation
✅ Deploy Preview for agent-sandbox canceled.
|
|
Hi @noeljackson. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
There was a problem hiding this comment.
Pull request overview
This PR tightens warm-pool sandbox adoption to avoid adopting sandboxes during pod-rotation gaps (when the backing Pod is absent), and introduces an API placeholder for future warm-pool adoption strategies on SandboxTemplate.
Changes:
- Update warm-pool adoptability checks to require
Sandbox.Status.PodIPsto be non-empty (proxy for “backing Pod exists and is networked”). - Add
SandboxTemplate.spec.adoptionStrategy(enum; default/current valueOldestReady) as an API surface for future strategy extensions. - Update/extend SandboxClaim adoption tests and fixtures to reflect the new adoptability signal.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
k8s/crds/extensions.agents.x-k8s.io_sandboxtemplates.yaml |
Adds CRD schema for spec.adoptionStrategy with default/enum. |
extensions/api/v1alpha1/sandboxtemplate_types.go |
Introduces WarmPoolAdoptionStrategy type/const and SandboxTemplateSpec.AdoptionStrategy. |
extensions/controllers/sandboxclaim_controller.go |
Tightens isAdoptable to skip candidates without Status.PodIPs. |
extensions/controllers/sandboxclaim_controller_test.go |
Updates fixtures and adds regression scenarios around rotation/no-backing-pod behavior. |
extensions/controllers/sandboxclaim_pod_exclusivity_test.go |
Updates warm pool sandbox fixtures to include Status.PodIPs so they remain adoptable. |
90733fb to
3a525c7
Compare
|
Force-pushed addressing both Copilot inline comments and rebased onto current
|
3a525c7 to
6b312ea
Compare
6b312ea to
e1f7830
Compare
|
/lgtm |
|
/lgtm PodIPs is the right adoption boundary here — the core controller clears |
|
/retest |
aditya-shantanu
left a comment
There was a problem hiding this comment.
The narrower boundary is the right call, and the mechanics check out: the core Sandbox controller clears Status.PodIPs when the backing Pod is gone and repopulates it from pod status, skipped keys are only re-added after the pop loop exits (no livelock), and the fallback/skipped interplay in getCandidate is preserved. One advisory consideration inline; not blocking.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
extensions/controllers/sandboxclaim_controller.go:1997
- This code introduces a bounded grace period (requeue via warmCandidatesPendingError) when all warm candidates are skipped for missing PodIPs. The PR description currently says the claim “falls through to cold creation for that reconcile” when every queued candidate is skipped; that’s not accurate during the grace window.
Suggested action: update the PR description to explicitly mention the grace-period requeue behavior (and that cold creation happens only after the grace expires), so reviewers/operators don’t misinterpret the new control flow.
if pendingNetworkCandidates > 0 {
if retryAfter, ok := warmCandidateRetryAfter(claim, time.Now()); ok {
return nil, &warmCandidatesPendingError{
pendingCandidates: pendingNetworkCandidates,
retryAfter: retryAfter,
extensions/controllers/sandboxclaim_controller_test.go:2138
- This regression case currently relies on the shared claim fixture having a zero CreationTimestamp, which bypasses the new warm-candidate grace logic and forces an immediate cold start. In real clusters CreationTimestamp is always set, so this test won’t exercise the production path unless it’s explicitly simulating a claim that’s already past the grace deadline.
Consider setting a non-zero CreationTimestamp here (e.g., older than warmCandidateGracePeriod) to make the intent explicit and keep the fixture closer to real API-server objects.
Reminder: please don’t use GitHub’s “Commit suggestion” button for AI suggestions (it can add an AI co-author and break the Kubernetes CLA check); apply the change locally instead.
claim,
|
@janetkuo The requested changes and all inline threads are now addressed at 69c533b. The all-candidates-unnetworked case uses a bounded two-second grace with 500 ms retries, distinguishes genuine pool exhaustion, and emits a fixed-reason fallback log before cold creation. Full local tests and fast presubmits are green; long e2e/benchmark jobs remain in progress. Could you please re-review? @aditya-shantanu, your advisory PodIPs/fallback thread is also addressed and resolved. |
|
/lgtm |
|
Rebased onto current upstream/main at 47458e0. The final grace-period thread is addressed and resolved: the two-second Pod IPAM window and bounded cold-start fallback are now documented. Local |
|
@noeljackson: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: aditya-shantanu, janetkuo, noeljackson The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What this PR does / why we need it:
During a warm-pool rotation, a Sandbox can remain queued while its backing Pod is being recreated. Adopting that Sandbox before the controller has observed Pod networking leaves the claim bound to unusable capacity.
This PR keeps static ownership and validity checks in
isAdoptableand treats cachedStatus.PodIPsas a transient selection signal ingetCandidate:warm_candidates_network_pendingbefore falling back to cold creation.PodIPsstatus cannot abandon it.Status.PodIPsis cached evidence, not an authoritative Pod-existence check: it narrows the rotation race but cannot eliminate every concurrent deletion window. The bounded retry is intentionally write-free and uses the claim creation timestamp as its deadline, preserving bounded claim startup latency and controller restart safety.This is a resubmission of #519 with the unused
adoptionStrategyAPI removed. Selection strategy should be designed separately once there is a concrete second strategy.Which issue(s) this PR is related to:
Ref #491
Ref #519
Testing
go test ./extensions/controllers -count=1make lint-gomake buildTMPDIR=$PWD/dev/tools/tmp make test-unitRegression coverage includes pool exhaustion, all-candidates-network-pending, grace expiry, adoption after networking becomes observable, queue preservation, and assigned-sandbox recovery.
Release Note