Skip to content

Commit c4a9772

Browse files
dcoliversundongjoon-hyun
authored andcommitted
[SPARK-37713][K8S] Assign namespace to executor configmap
### What changes were proposed in this pull request? Since Spark 3.X, Executor pod needs separate executor configmap. But, no namespace is assigned in configmap while building it. K8s views configmap without namespace as global resource. Once pod access is restricted (global resources cannot be read), and executor cannot obtain configmap itself. ### Why are the changes needed? Fix executor pod authorization error in K8S. When executor pod cannot read global resources, executor configmap is not available for executor. ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? Pass Integration Test and CIs. Closes #34983 from dcoliversun/SPARK-37713. Authored-by: Qian.Sun <[email protected]> Signed-off-by: Dongjoon Hyun <[email protected]>
1 parent 8b2e426 commit c4a9772

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/submit/KubernetesClientUtils.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import io.fabric8.kubernetes.api.model.{ConfigMap, ConfigMapBuilder, KeyToPath}
2929

3030
import org.apache.spark.SparkConf
3131
import org.apache.spark.deploy.k8s.{Config, Constants, KubernetesUtils}
32-
import org.apache.spark.deploy.k8s.Config.KUBERNETES_DNSNAME_MAX_LENGTH
32+
import org.apache.spark.deploy.k8s.Config.{KUBERNETES_DNSNAME_MAX_LENGTH, KUBERNETES_NAMESPACE}
3333
import org.apache.spark.deploy.k8s.Constants.ENV_SPARK_CONF_DIR
3434
import org.apache.spark.internal.Logging
3535

@@ -89,9 +89,12 @@ private[spark] object KubernetesClientUtils extends Logging {
8989
*/
9090
def buildConfigMap(configMapName: String, confFileMap: Map[String, String],
9191
withLabels: Map[String, String] = Map()): ConfigMap = {
92+
val configMapNameSpace =
93+
confFileMap.getOrElse(KUBERNETES_NAMESPACE.key, KUBERNETES_NAMESPACE.defaultValueString)
9294
new ConfigMapBuilder()
9395
.withNewMetadata()
9496
.withName(configMapName)
97+
.withNamespace(configMapNameSpace)
9598
.withLabels(withLabels.asJava)
9699
.endMetadata()
97100
.withImmutable(true)

resource-managers/kubernetes/core/src/main/scala/org/apache/spark/scheduler/cluster/k8s/KubernetesClusterSchedulerBackend.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ private[spark] class KubernetesClusterSchedulerBackend(
7676

7777
private def setUpExecutorConfigMap(driverPod: Option[Pod]): Unit = {
7878
val configMapName = KubernetesClientUtils.configMapNameExecutor
79+
val resolvedExecutorProperties =
80+
Map(KUBERNETES_NAMESPACE.key -> conf.get(KUBERNETES_NAMESPACE))
7981
val confFilesMap = KubernetesClientUtils
80-
.buildSparkConfDirFilesMap(configMapName, conf, Map.empty)
82+
.buildSparkConfDirFilesMap(configMapName, conf, resolvedExecutorProperties)
8183
val labels =
8284
Map(SPARK_APP_ID_LABEL -> applicationId(), SPARK_ROLE_LABEL -> SPARK_POD_EXECUTOR_ROLE)
8385
val configMap = KubernetesClientUtils.buildConfigMap(configMapName, confFilesMap, labels)

resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/submit/KubernetesClientUtilsSuite.scala

+27
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ package org.apache.spark.deploy.k8s.submit
2020
import java.io.File
2121
import java.nio.charset.StandardCharsets
2222
import java.nio.file.Files
23+
import java.util.UUID
2324

25+
import scala.collection.JavaConverters._
26+
27+
import io.fabric8.kubernetes.api.model.ConfigMapBuilder
2428
import org.scalatest.BeforeAndAfter
2529

2630
import org.apache.spark.{SparkConf, SparkFunSuite}
@@ -76,4 +80,27 @@ class KubernetesClientUtilsSuite extends SparkFunSuite with BeforeAndAfter {
7680
"testConf.3" -> "test123456")
7781
assert(output === expectedOutput)
7882
}
83+
84+
test("verify that configmap built as expected") {
85+
val configMapName = s"configmap-name-${UUID.randomUUID.toString}"
86+
val configMapNameSpace = s"configmap-namespace-${UUID.randomUUID.toString}"
87+
val properties = Map(Config.KUBERNETES_NAMESPACE.key -> configMapNameSpace)
88+
val sparkConf =
89+
testSetup(properties.map(f => f._1 -> f._2.getBytes(StandardCharsets.UTF_8)))
90+
val confFileMap =
91+
KubernetesClientUtils.buildSparkConfDirFilesMap(configMapName, sparkConf, properties)
92+
val outputConfigMap =
93+
KubernetesClientUtils.buildConfigMap(configMapName, confFileMap, properties)
94+
val expectedConfigMap =
95+
new ConfigMapBuilder()
96+
.withNewMetadata()
97+
.withName(configMapName)
98+
.withNamespace(configMapNameSpace)
99+
.withLabels(properties.asJava)
100+
.endMetadata()
101+
.withImmutable(true)
102+
.addToData(confFileMap.asJava)
103+
.build()
104+
assert(outputConfigMap === expectedConfigMap)
105+
}
79106
}

0 commit comments

Comments
 (0)