peter-toth commented on code in PR #975:
URL: 
https://github.com/apache/spark-kubernetes-operator/pull/975#discussion_r4334882853


##########
spark-operator-api/src/main/java/org/apache/spark/k8s/operator/utils/ModelUtils.java:
##########
@@ -83,15 +92,36 @@ public static List<ContainerStatus> 
findDriverMainContainerStatus(
     if (appSpec == null) {
       return containerStatusList;
     }
-    Map<String, String> sparkConf = appSpec.getSparkConf();
-    String key = sparkConf.get(DRIVER_SPARK_CONTAINER_PROP_KEY);
-    if (key == null || key.isEmpty()) {
-      return containerStatusList;
+    String mainContainerName = getDriverMainContainerName(appSpec);
+    List<ContainerStatus> mainContainerStatusList =
+        containerStatusList.stream()
+            .filter(c -> mainContainerName.equalsIgnoreCase(c.getName()))
+            .collect(Collectors.toList());
+    return mainContainerStatusList.isEmpty() ? containerStatusList : 
mainContainerStatusList;
+  }
+
+  /**
+   * Returns the name of the driver container, which Spark selects from the 
pod template like
+   * KubernetesUtils.selectSparkContainer and names like 
BasicDriverFeatureStep.
+   */
+  private static String getDriverMainContainerName(final ApplicationSpec 
appSpec) {
+    String containerName = 
appSpec.getSparkConf().get(DRIVER_SPARK_CONTAINER_PROP_KEY);
+    if (!overrideDriverTemplateEnabled(appSpec)) {
+      return containerName == null || containerName.isEmpty()

Review Comment:
   **Finding 1.** Without a pod template in the spec, Spark reads 
`spark.kubernetes.driver.podTemplateContainerName` only when it loads 
`spark.kubernetes.driver.podTemplateFile` 
([`KubernetesDriverBuilder`](https://github.com/apache/spark/blob/v4.2.0/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/submit/KubernetesDriverBuilder.scala#L42-L50)).
 Otherwise it starts from `SparkPod.initialPod()`, and `BasicDriverFeatureStep` 
names the container `spark-kubernetes-driver`.
   
   Here the property wins whenever it is set, even without a template file. 
Then no container status has that name, so all containers count again. I ran 
the observers at this head with the property set to `driver` and the statuses 
`[istio-proxy, spark-kubernetes-driver]`:
   
   - `istio-proxy` exited with 0 or 1 and the driver is running. 
`AppDriverReadyObserver` returns `Succeeded` or `Failed`.
   - `istio-proxy` is ready and the driver is not. `AppDriverStartObserver` 
returns `DriverStarted`.
   
   Using the property only with a template file, like Spark, fixes it (plus the 
static import of `DRIVER_SPARK_TEMPLATE_FILE_PROP_KEY`):
   
   ```java
       if (!overrideDriverTemplateEnabled(appSpec)) {
         // Like Spark, the property applies only to a pod template file.
         return containerName == null
                 || containerName.isEmpty()
                 || 
!appSpec.getSparkConf().containsKey(DRIVER_SPARK_TEMPLATE_FILE_PROP_KEY)
             ? DEFAULT_DRIVER_CONTAINER_NAME
             : containerName;
       }
   ```
   
   With it, all three cases return empty, and the PR's tests pass. The only 
test to update is the second half of `testFindDriverMainContainerStatus`, which 
needs `spark.kubernetes.driver.podTemplateFile` in its `sparkProps`. The 
javadoc sentence starting "Without the pod template in the application 
specification" would then name the pod template file too.
   



##########
docs/migration_guide.md:
##########
@@ -172,6 +172,23 @@ affect building the project, CI, tests or examples.
   `driverStartTimeoutMillis` was disabled. Since `DriverStartTimedOut` is an 
infrastructure failure
   while the others are not, `restartPolicy: OnInfrastructureFailure` no longer 
restarts such an
   application. Use `OnFailure` to restart it.
+- Since 1.1.0, only the driver container of the driver pod decides whether the 
application has
+  started, succeeded or failed. Like Apache Spark, it is the container of the 
driver pod template
+  which `spark.kubernetes.driver.podTemplateContainerName` names, or else its 
first container, or
+  `spark-kubernetes-driver` without a pod template. 1.0 considered all 
containers unless the
+  property was set, so an application moved to `Succeeded` or `Failed` as soon 
as a sidecar
+  container, e.g. a log collector or `istio-proxy`, exited, and its driver pod 
was deleted while
+  the driver was still running, unless `resourceRetainPolicy` retained it. 
Likewise, an
+  application with a sidecar container moves to `DriverStarted` when the 
driver container is ready
+  instead of any container, so a driver container whose image cannot be pulled 
ends in
+  `DriverStartTimedOut`, which `restartPolicy: OnInfrastructureFailure` 
restarts, instead of
+  `DriverReadyTimedOut`. If the driver container is not found, e.g. since the 
first container of

Review Comment:
   **Finding 2.** One more consequence the guide doesn't cover. 
`AppDriverReadyObserver` still moves to `DriverReady` only on the pod's `Ready` 
condition, which counts every container. So a regular sidecar container which 
exits before the pod is first ready keeps the pod not ready for good, e.g. a 
log collector which crashes at start.
   
   - 1.0 moved such an app to `Failed`, or `Succeeded` on exit code 0, right 
away.
   - Now the driver keeps running, and the app ends as `DriverReadyTimedOut` 
after `driverReadyTimeoutMillis`, 5 minutes by default.
   
   I checked it at this head with a `DriverStarted` state 301 seconds old, a 
`Ready=False` condition and the statuses `[log-collector (exit 1), 
spark-kubernetes-driver (running, ready)]`. `AppDriverReadyObserver` and 
`AppDriverRunningObserver` return empty, and `AppDriverTimeoutObserver` returns 
`DriverReadyTimedOut`. With `ModelUtils` and `BaseAppDriverObserver` reverted, 
both observers return `Failed`.
   
   The new end state is arguably right. The driver service is headless without 
`publishNotReadyAddresses`, so executors cannot resolve a driver pod that is 
not ready. A sentence after the `DriverStarted` one would cover it, e.g.:
   
   ```markdown
   Similarly, an application whose sidecar container exits before the driver 
pod is ready ends in `DriverReadyTimedOut` after `driverReadyTimeoutMillis`, 
instead of `Failed` or `Succeeded` right away.
   ```
   



-- 
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