Skip to content

[SPARK-58113][K8S] Support publishNotReadyAddresses in driver service#57242

Closed
j1wonpark wants to merge 2 commits into
apache:masterfrom
j1wonpark:SPARK-58113-publish-not-ready
Closed

[SPARK-58113][K8S] Support publishNotReadyAddresses in driver service#57242
j1wonpark wants to merge 2 commits into
apache:masterfrom
j1wonpark:SPARK-58113-publish-not-ready

Conversation

@j1wonpark

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Add a new configuration spark.kubernetes.driver.service.publishNotReadyAddresses (boolean, default false).

When enabled:

  • DriverServiceFeatureStep sets spec.publishNotReadyAddresses: true on the headless driver service, so DNS records for the driver pod are published even while the pod is not Ready.
  • The driver pod readiness wait before executor allocation (introduced in SPARK-32975) is skipped in ExecutorPodsAllocator, StatefulSetPodsAllocator, and DeploymentPodsAllocator, since the sole purpose of that wait — ensuring the headless service is resolvable by DNS before executors start — no longer depends on pod readiness.

Why are the changes needed?

Kubernetes publishes DNS records for a headless service only for Ready pods. Users commonly attach a readiness probe to the driver pod through spark.kubernetes.driver.podTemplateFile — a typical setup for long-running Spark Connect servers, where pod readiness gates traffic routing. When such a probe gates on a port that binds after SparkContext initialization completes (e.g. the Spark Connect gRPC port), executors launched during initialization cannot resolve the driver service and die with UnknownHostException. With static allocation, maxNumExecutorFailures = max(3, 2 * spark.executor.instances) is reached before initialization can complete, and the driver exits with code 11 (EXCEED_MAX_EXECUTOR_FAILURES) on every attempt — the application can never start.

The existing mitigation from SPARK-32975 (waitUntilReady in the allocators, tunable via spark.kubernetes.allocation.driver.readinessTimeout per SPARK-49079) cannot help here: the wait runs inside SparkContext initialization, while such a probe can only pass after initialization completes, so the wait always burns the full timeout and the race resumes.

The driver service is a single-pod discovery endpoint rather than a load-balancing service, and publishNotReadyAddresses is the standard Kubernetes pattern for headless discovery services. There is currently no first-class way to set it — the service spec is not customizable via pod templates, and the only workarounds are re-implementing the service in a custom feature step (via spark.kubernetes.driver.pod.excludedFeatureSteps) or cluster-level admission webhooks. This follows the precedent of exposing driver service spec fields as configurations (SPARK-39490: ipFamilyPolicy/ipFamilies).

The configuration is opt-in (default false) because publishing not-ready addresses is not desirable for deployments that rely on endpoint readiness to gate traffic to the driver service (e.g. through a service mesh); flipping the default could be discussed separately.

Does this PR introduce any user-facing change?

No change by default. A new opt-in configuration is added and documented in running-on-kubernetes.md.

How was this patch tested?

New unit tests:

  • DriverServiceFeatureStepSuite: the default leaves the field false; enabling the configuration sets it to true.
  • ExecutorPodsAllocatorSuite, StatefulSetAllocatorSuite, DeploymentAllocatorSuite: the driver pod readiness wait still runs by default, and enabling the configuration skips it (waitUntilReady is not invoked).

Also verified the behavior end-to-end on a real Kubernetes cluster by applying publishNotReadyAddresses: true to the driver service through an admission webhook (equivalent to what this configuration does): executors resolved the driver service and registered while the driver pod was still NotReady behind a Spark Connect port readiness probe, and a static-allocation application that previously failed on every attempt with exit code 11 started successfully.

Was this patch authored or co-authored using generative AI tooling?

Yes. Co-authored with Claude Opus.

Signed-off-by: Jiwon Park <jpark92@outlook.kr>
@dongjoon-hyun dongjoon-hyun changed the title [SPARK-58113][K8S] Support publishNotReadyAddresses in driver service [SPARK-58113][K8S] Support publishNotReadyAddresses in driver service Jul 14, 2026

@dongjoon-hyun dongjoon-hyun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for making a PR, @j1wonpark . The code looks reasonable to me. Please add a binding policy.

Signed-off-by: Jiwon Park <jpark92@outlook.kr>
<td><code>false</code></td>
<td>
If true, the driver service publishes DNS records for the driver pod even while the pod
is not ready, so executors can resolve the driver service during startup when a readiness

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: the rationale "so executors can resolve the driver service during startup" only holds when spark.kubernetes.executor.useDriverPodIP=false. That config defaults to true (since 4.1.0+), where the executor's driverAddress is DRIVER_BIND_ADDRESS (the pod IP) and executors never DNS-resolve the driver service; so in the default configuration this option, and the readiness wait it bypasses, are moot. A user reading only this entry may enable it believing it helps the default setup. One clarifying sentence (only meaningful when useDriverPodIP=false) in both the config doc and the docs table would close the gap.

@uros-b uros-b left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, thank you @j1wonpark - @dongjoon-hyun PTAL, also cc @cchriswu @pan3793

@dongjoon-hyun dongjoon-hyun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, LGTM.

dongjoon-hyun pushed a commit that referenced this pull request Jul 15, 2026
### What changes were proposed in this pull request?

Add a new configuration `spark.kubernetes.driver.service.publishNotReadyAddresses` (boolean, default `false`).

When enabled:
- `DriverServiceFeatureStep` sets `spec.publishNotReadyAddresses: true` on the headless driver service, so DNS records for the driver pod are published even while the pod is not Ready.
- The driver pod readiness wait before executor allocation (introduced in SPARK-32975) is skipped in `ExecutorPodsAllocator`, `StatefulSetPodsAllocator`, and `DeploymentPodsAllocator`, since the sole purpose of that wait — ensuring the headless service is resolvable by DNS before executors start — no longer depends on pod readiness.

### Why are the changes needed?

Kubernetes publishes DNS records for a headless service only for Ready pods. Users commonly attach a readiness probe to the driver pod through `spark.kubernetes.driver.podTemplateFile` — a typical setup for long-running Spark Connect servers, where pod readiness gates traffic routing. When such a probe gates on a port that binds after `SparkContext` initialization completes (e.g. the Spark Connect gRPC port), executors launched during initialization cannot resolve the driver service and die with `UnknownHostException`. With static allocation, `maxNumExecutorFailures = max(3, 2 * spark.executor.instances)` is reached before initialization can complete, and the driver exits with code 11 (`EXCEED_MAX_EXECUTOR_FAILURES`) on every attempt — the application can never start.

The existing mitigation from SPARK-32975 (`waitUntilReady` in the allocators, tunable via `spark.kubernetes.allocation.driver.readinessTimeout` per SPARK-49079) cannot help here: the wait runs inside `SparkContext` initialization, while such a probe can only pass after initialization completes, so the wait always burns the full timeout and the race resumes.

The driver service is a single-pod discovery endpoint rather than a load-balancing service, and `publishNotReadyAddresses` is the standard Kubernetes pattern for headless discovery services. There is currently no first-class way to set it — the service spec is not customizable via pod templates, and the only workarounds are re-implementing the service in a custom feature step (via `spark.kubernetes.driver.pod.excludedFeatureSteps`) or cluster-level admission webhooks. This follows the precedent of exposing driver service spec fields as configurations (SPARK-39490: `ipFamilyPolicy`/`ipFamilies`).

The configuration is opt-in (default `false`) because publishing not-ready addresses is not desirable for deployments that rely on endpoint readiness to gate traffic to the driver service (e.g. through a service mesh); flipping the default could be discussed separately.

### Does this PR introduce _any_ user-facing change?

No change by default. A new opt-in configuration is added and documented in `running-on-kubernetes.md`.

### How was this patch tested?

New unit tests:
- `DriverServiceFeatureStepSuite`: the default leaves the field `false`; enabling the configuration sets it to `true`.
- `ExecutorPodsAllocatorSuite`, `StatefulSetAllocatorSuite`, `DeploymentAllocatorSuite`: the driver pod readiness wait still runs by default, and enabling the configuration skips it (`waitUntilReady` is not invoked).

Also verified the behavior end-to-end on a real Kubernetes cluster by applying `publishNotReadyAddresses: true` to the driver service through an admission webhook (equivalent to what this configuration does): executors resolved the driver service and registered while the driver pod was still NotReady behind a Spark Connect port readiness probe, and a static-allocation application that previously failed on every attempt with exit code 11 started successfully.

### Was this patch authored or co-authored using generative AI tooling?

Yes. Co-authored with Claude Opus.

Closes #57242 from j1wonpark/SPARK-58113-publish-not-ready.

Authored-by: Jiwon Park <jpark92@outlook.kr>
Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
(cherry picked from commit 01b3c25)
Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
@dongjoon-hyun

Copy link
Copy Markdown
Member

Merge Summary:

Posted by merge_spark_pr.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants