docs: document that endpoint discovery honours custom pod readinessGates - #2604
Open
almogtavor wants to merge 2 commits into
Open
docs: document that endpoint discovery honours custom pod readinessGates#2604almogtavor wants to merge 2 commits into
almogtavor wants to merge 2 commits into
Conversation
The EPP admits a pod into the routing pool only when the pod's aggregate Ready condition is True. The kubelet computes Ready as ContainersReady AND every condition named in spec.readinessGates, so custom readiness gates already gate routing fail-closed, with no EPP configuration required. That was not written down anywhere, so it was not discoverable. Document the contract in docs/discovery.md, including the point that a gated pod still shows 1/1 in kubectl get pods because that column counts ready containers, not the Ready condition. Add IsPodReady cases for a satisfied and an unsatisfied readiness gate so the behaviour is pinned. The unsatisfied case fails if IsPodReady is ever switched from PodReady to ContainersReady. Signed-off-by: Almog Tavor <almogtavor@gmail.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Documents how the EPP’s Kubernetes pod discovery determines readiness (by reading the pod’s PodReady condition) and adds unit tests that pin readiness-gate behavior via that contract.
Changes:
- Document that Kubernetes discovery admits pods only when the aggregate
Ready(PodReady) condition isTrue, which implicitly honorsspec.readinessGates. - Add
IsPodReadyunit tests covering both satisfied and unsatisfied readiness-gate scenarios.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
pkg/epp/util/pod/pod_test.go |
Adds unit test cases that ensure readiness-gated pods are excluded unless PodReady is True. |
docs/discovery.md |
Adds a Kubernetes discovery readiness section explaining how PodReady (and thus readiness gates) controls routing eligibility. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
omerap12
reviewed
Aug 31, 2026
Comment on lines
+129
to
+131
| // The kubelet ANDs every readiness gate into PodReady, so an | ||
| // unsatisfied gate holds PodReady at False even though the | ||
| // containers themselves are ready. |
Contributor
There was a problem hiding this comment.
nit: not sure if those comments are needed.
Comment on lines
+86
to
+91
| This is a **fail-closed** contract, which is what makes readiness gates useful | ||
| for out-of-band lifecycle managers -- checkpoint restorers, warm-up agents, and | ||
| dynamic weight loaders -- that need to hold traffic back until work that the | ||
| container probes cannot observe has finished. Note that a gated pod still shows | ||
| `1/1` in `kubectl get pods`, because that column counts ready *containers*; the | ||
| `Ready` **condition** is the one the EPP reads. |
Contributor
There was a problem hiding this comment.
nit: not sure if those comments are needed.
Drop the inline kubelet explanation from the test case and condense the closing paragraph in docs/discovery.md, keeping the 1/1 vs Ready-condition note that is the non-obvious part. Signed-off-by: Almog Tavor <almogtavor@gmail.com>
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.
What type of PR is this?
/kind documentation
What this PR does / why we need it:
The issue asks whether the router honours custom pod
readinessGates, and notes"the router may already support this; I just couldn't find any documentation."
It does, and it already behaves exactly as requested. Every readiness decision in
the EPP goes through
podutil.IsPodReady(pkg/epp/util/pod/pod.go), which readsthe pod's aggregate
Readycondition. The kubelet computesReadyasContainersReadyAND every condition listed inspec.readinessGates, so anunsatisfied gate holds the pod out of the routing pool with no EPP configuration
required, fail-closed. The same is true of the other two readiness call sites
(
pkg/epp/datastore/datastore.go, the topology extractor).So the gap was purely that this was never written down. This PR:
docs/discovery.md, including the detail that agated pod still shows
1/1inkubectl get pods(that column counts readycontainers, not the
Readycondition) -- which is the thing that makes thisconfusing to verify by hand.
IsPodReadycases for a satisfied and an unsatisfied readiness gate, sothe behaviour is pinned rather than incidental.
The unsatisfied-gate case has teeth: switching
IsPodReadyfromcorev1.PodReadyto
corev1.ContainersReadyfails it.Verification (OpenShift 4.21 / k8s v1.32, live EPP against an InferencePool):
Two pods labelled for the pool, one with
readinessGates: [custom.orchestrator.io/serving]:The EPP admitted only the ungated pod:
{"msg":"Pod added","name":"vllm-ungated"}Patching the gate condition to
TrueflippedReady=True, and the EPP picked thepod up on the next reconcile:
{"msg":"Pod added","name":"vllm-gated"}This also covers the use cases in the issue -- checkpoint restorers, out-of-band
warm-up agents, dynamic weight loaders -- and the llm-d/llm-d#2365
Snapshot Orchestrator integration it references.
If maintainers would rather also see this asserted end-to-end against a live pool,
I'm happy to add an integration test; I kept the PR to docs plus a unit-level pin
since the behaviour itself needs no change.
Which issue(s) this PR fixes:
Fixes #2541
Release note: