You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by do...@apache.org on 2026/04/30 04:26:34 UTC
(spark) branch master updated: [SPARK-56670][K8S] Restrict `ExecutorResizePlugin` to `direct` pods allocator
This is an automated email from the ASF dual-hosted git repository.
dongjoon-hyun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 4022753b2523 [SPARK-56670][K8S] Restrict `ExecutorResizePlugin` to `direct` pods allocator
4022753b2523 is described below
commit 4022753b2523ec0601eaaa8318a9ae8a02a5f524
Author: Dongjoon Hyun <do...@apache.org>
AuthorDate: Wed Apr 29 21:26:24 2026 -0700
[SPARK-56670][K8S] Restrict `ExecutorResizePlugin` to `direct` pods allocator
### What changes were proposed in this pull request?
This PR restricts `ExecutorResizePlugin` to activate only when the `direct` pods allocator (`ExecutorPodsAllocator`) is configured via `spark.kubernetes.allocation.pods.allocator`.
When the configured allocator is anything else (`statefulset`, `deployment`, or a user-supplied class), `ExecutorResizeDriverPlugin.init()` now logs a warning and returns early without creating a Kubernetes client or
scheduling the periodic memory check.
### Why are the changes needed?
`ExecutorResizePlugin` resizes individual executor pods in place via `pods().withName(...).subresource("resize").patch(...)`. This works correctly only when Spark itself owns each pod, i.e. with the `direct` allocator. For the other allocators, user-defined or the higher-level controller's pod template is the source of truth and patching a single pod under those allocators may have unexpected side-effects.
- `statefulset` → `StatefulSet.spec.template`
- `deployment` → `Deployment.spec.template`
### Does this PR introduce _any_ user-facing change?
No, `ExecutorResizePlugin` is a new unreleased feature of Apache Spark 4.2.0.
### How was this patch tested?
Pass the CIs with the newly added test coverage.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.7)
Closes #55615 from dongjoon-hyun/SPARK-56670.
Authored-by: Dongjoon Hyun <do...@apache.org>
Signed-off-by: Dongjoon Hyun <do...@apache.org>
---
.../cluster/k8s/ExecutorResizePlugin.scala | 10 +++++++++-
.../cluster/k8s/ExecutorResizePluginSuite.scala | 21 ++++++++++++++++++++-
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/scheduler/cluster/k8s/ExecutorResizePlugin.scala b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/scheduler/cluster/k8s/ExecutorResizePlugin.scala
index 77fd37dd538b..d5d882978dfc 100644
--- a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/scheduler/cluster/k8s/ExecutorResizePlugin.scala
+++ b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/scheduler/cluster/k8s/ExecutorResizePlugin.scala
@@ -32,7 +32,7 @@ import org.apache.spark.deploy.k8s.Config._
import org.apache.spark.deploy.k8s.Constants._
import org.apache.spark.deploy.k8s.SparkKubernetesClientFactory
import org.apache.spark.internal.Logging
-import org.apache.spark.internal.LogKeys.{EXECUTOR_ID, MEMORY_SIZE}
+import org.apache.spark.internal.LogKeys.{CONFIG, CONFIG2, EXECUTOR_ID, MEMORY_SIZE}
import org.apache.spark.util.{ThreadUtils, Utils}
/**
@@ -53,6 +53,14 @@ class ExecutorResizeDriverPlugin extends DriverPlugin with Logging {
ThreadUtils.newDaemonSingleThreadScheduledExecutor("executor-resize-plugin")
override def init(sc: SparkContext, ctx: PluginContext): JMap[String, String] = {
+ val allocator = sc.conf.get(KUBERNETES_ALLOCATION_PODS_ALLOCATOR)
+ if (allocator != "direct") {
+ logWarning(log"ExecutorResizePlugin requires the 'direct' pods allocator; " +
+ log"${MDC(CONFIG, KUBERNETES_ALLOCATION_PODS_ALLOCATOR.key)} is " +
+ log"${MDC(CONFIG2, allocator)}. Plugin will not start.")
+ return Map.empty[String, String].asJava
+ }
+
val interval = Utils.timeStringAsSeconds(
sc.conf.get(EXECUTOR_RESIZE_INTERVAL.key, "1m"))
val threshold = sc.conf.getDouble(EXECUTOR_RESIZE_THRESHOLD.key, 0.9)
diff --git a/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/scheduler/cluster/k8s/ExecutorResizePluginSuite.scala b/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/scheduler/cluster/k8s/ExecutorResizePluginSuite.scala
index 649ccd8a945d..e8ce7d44abd0 100644
--- a/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/scheduler/cluster/k8s/ExecutorResizePluginSuite.scala
+++ b/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/scheduler/cluster/k8s/ExecutorResizePluginSuite.scala
@@ -29,7 +29,9 @@ import org.mockito.Mockito.{mock, never, times, verify, when}
import org.scalatest.BeforeAndAfter
import org.scalatest.PrivateMethodTester
-import org.apache.spark.{SparkContext, SparkFunSuite}
+import org.apache.spark.{SparkConf, SparkContext, SparkFunSuite}
+import org.apache.spark.api.plugin.PluginContext
+import org.apache.spark.deploy.k8s.Config.KUBERNETES_ALLOCATION_PODS_ALLOCATOR
import org.apache.spark.deploy.k8s.Constants._
import org.apache.spark.deploy.k8s.Fabric8Aliases._
@@ -287,4 +289,21 @@ class ExecutorResizePluginSuite
verify(podResource, times(1)).patch(any(), any(classOf[Pod]))
}
+
+ Seq("statefulset", "deployment").foreach { allocator =>
+ test(s"init returns early when pods allocator is '$allocator'") {
+ val plugin = new ExecutorResizeDriverPlugin()
+ val sparkConf = new SparkConf().set(KUBERNETES_ALLOCATION_PODS_ALLOCATOR, allocator)
+ val sc = mock(classOf[SparkContext])
+ when(sc.conf).thenReturn(sparkConf)
+ val pluginCtx = mock(classOf[PluginContext])
+
+ val result = plugin.init(sc, pluginCtx)
+
+ assert(result.isEmpty)
+ val clientField = plugin.getClass.getDeclaredField("kubernetesClient")
+ clientField.setAccessible(true)
+ assert(clientField.get(plugin) == null)
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org