HwangDongJun opened a new pull request, #58187:
URL: https://github.com/apache/spark/pull/58187

   ### What changes were proposed in this pull request?
   
   When submitting a Spark application to Kubernetes in cluster mode, several
   resources that the driver pod mounts as volumes were being created *after*
   the driver pod itself, via the `getAdditionalKubernetesResources()` hook.
   This PR switches them to use the existing (but previously unused)
   `getAdditionalPreKubernetesResources()` hook instead, so they are created
   *before* the driver pod:
   
   * `KubernetesClientApplication.Client.run()`: the driver's own base config
     map (mounted as `SPARK_CONF_VOLUME_DRIVER`) is now included in
     `preKubernetesResources` instead of `otherKubernetesResources`.
   * `HadoopConfDriverFeatureStep`: the Hadoop conf config map.
   * `KerberosConfDriverFeatureStep`: the krb5 conf config map, the keytab
     secret, and the delegation token secret.
   * `PodTemplateConfigMapStep`: the executor pod template config map (mounted
     on the driver pod, which reads it when building executor pod specs).
   * `DriverKubernetesCredentialsFeatureStep`: the secret holding the driver's
     submission-time Kubernetes client credentials, when
     `spark.kubernetes.authenticate.driver.*` file-based credentials are used.
   
   `MountVolumesFeatureStep` (which can create an on-demand 
`PersistentVolumeClaim`)
   is intentionally left unchanged: it is shared between the driver and executor
   builders, and `KubernetesExecutorBuilder` has no equivalent "pre-resource"
   concept, so switching it would silently break on-demand PVC creation for
   executors.
   
   ### Why are the changes needed?
   
   Kubernetes creates the driver pod and the config maps/secrets it depends on
   via separate, sequential API calls. If the pod is created before its config
   map/secret exists, the kubelet can attempt to mount it too early, producing
   events like:
   
   Warning  FailedMount   MountVolume.SetUp failed for volume 
"spark-conf-volume-driver" :
                           configmap "spark-drv-70e59d88484c3e59-conf-map" not 
found
   Warning  FailedMount   MountVolume.SetUp failed for volume 
"hadoop-properties" :
                           configmap 
"spark-pi-6-a63eb888484c3bf1-hadoop-config" not found
   
   The kubelet usually retries and eventually succeeds, but under slower or
   more loaded API servers this race can cause the driver pod to fail to start
   altogether. `KubernetesFeatureConfigStep` already provides a
   `getAdditionalPreKubernetesResources()` hook meant for exactly this purpose
   (resources that must exist before the pod is created), but no feature step
   was using it; all of them used the post-pod-creation hook instead.
   
   This is analogous to SPARK-38794, which fixed the same class of race for the
   *executor* config map (by creating it before requesting executors). This PR
   addresses the remaining occurrences on the *driver* side.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No behavior change for successful submissions. It reduces the likelihood of
   transient "configmap/secret ... not found" mount warnings/failures for the
   driver pod during Kubernetes cluster-mode submission.
   
   ### How was this patch tested?
   
   * Added `ClientSuite`: `SPARK-38079: driver's own config map is created
     before the driver pod, to avoid a mount race`, asserting that the first
     `resourceList()` call (the pre-resources application, which happens
     before the driver pod is created) includes the driver's own config map.
     Reverted the fix locally and confirmed this test fails against the
     original code, then confirmed it passes with the fix applied.
   * Updated `ClientSuite`'s existing resource-count assertions (now the
     config map is sent twice via `resourceList()`: once before pod creation,
     once for the owner-reference refresh, matching the existing pattern for
     other pre-resources) and added a safety check that the config map still
     gets an owner reference set on the refresh call.
   * Updated `HadoopConfDriverFeatureStepSuite`, 
`KerberosConfDriverFeatureStepSuite`,
     `PodTemplateConfigMapStepSuite`, and 
`DriverKubernetesCredentialsFeatureStepSuite`
     to assert against `getAdditionalPreKubernetesResources()` instead of
     `getAdditionalKubernetesResources()`.
   * Ran the full `kubernetes/core` module test suite: 386/386 passed.
     `scalastyle`/`checkstyle`: no violations.
   * Live cluster verification (Kubernetes 1.x, no custom image needed since
     this is client-side submission logic): submitted `SparkPi` in cluster
     mode repeatedly against the same (unmodified) driver/executor image,
     toggling only which locally-built `spark-kubernetes` jar drove
     `spark-submit`.
     * Original code: 3 of 5 driver pods hit `FailedMount` for
       `spark-conf-volume-driver` (`configmap ... not found`), matching the
       reported symptom exactly. With
       `spark.kubernetes.authenticate.driver.oauthToken` set to exercise
       `DriverKubernetesCredentialsFeatureStep`, 2 of 5 driver pods hit
       `FailedMount` for the `kubernetes-credentials` secret.
     * With this patch applied: 0 `FailedMount` events across 10 runs of each
       scenario; `SparkPi` completed successfully with the correct result.
     * Confirmed no impact on other running services in the test namespace,
       and that config maps/secrets are still garbage-collected via owner
       references once the driver pod is deleted.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Sonnet 5


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to