Skip to content

Commit acdb078

Browse files
committed
[SPARK-58776][K8S] Propagate spark.ssl.rpc.* passwords to executors in BasicExecutorFeatureStep
1 parent 08d7c51 commit acdb078

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStep.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ private[spark] class BasicExecutorFeatureStep(
143143
case _ => Nil
144144
}.getOrElse(Nil)
145145

146+
// SparkConf.isExecutorStartupConf withholds the spark.ssl.* passwords from the
147+
// executor conf. Pass them through the environment, as the standalone worker
148+
// does in CommandUtils. Names the user already supplies via
149+
// spark.kubernetes.executor.secretKeyRef are skipped, so that an explicit
150+
// secret reference is not shadowed by a literal password in the pod spec.
151+
val sslRpcPasswords = secMgr.getEnvironmentForSslRpcPasswords.filterNot {
152+
case (name, _) => kubernetesConf.secretEnvNamesToKeyRefs.contains(name)
153+
}.toSeq
154+
146155
val userOpts = kubernetesConf.get(EXECUTOR_JAVA_OPTIONS).toSeq.flatMap { opts =>
147156
val subsOpts = Utils.substituteAppNExecIds(opts, kubernetesConf.appId,
148157
kubernetesConf.executorId)
@@ -187,6 +196,7 @@ private[spark] class BasicExecutorFeatureStep(
187196
++ attributes
188197
++ kubernetesConf.environment
189198
++ sparkAuthSecret
199+
++ sslRpcPasswords
190200
++ Seq(ENV_CLASSPATH -> kubernetesConf.get(EXECUTOR_CLASS_PATH).orNull)
191201
++ allOpts) ++
192202
KubernetesUtils.buildEnvVarsWithFieldRef(

resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/features/BasicExecutorFeatureStepSuite.scala

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import com.google.common.net.InternetDomainName
2424
import io.fabric8.kubernetes.api.model._
2525
import org.scalatest.BeforeAndAfter
2626

27-
import org.apache.spark.{SecurityManager, SparkConf, SparkException, SparkFunSuite, SparkIllegalArgumentException}
27+
import org.apache.spark.{SecurityManager, SparkConf, SparkException, SparkFunSuite, SparkIllegalArgumentException, SSLOptions}
2828
import org.apache.spark.deploy.k8s.{KubernetesExecutorConf, KubernetesTestConf, SecretVolumeUtils, SparkPod}
2929
import org.apache.spark.deploy.k8s.Config._
3030
import org.apache.spark.deploy.k8s.Constants._
@@ -417,6 +417,58 @@ class BasicExecutorFeatureStepSuite extends SparkFunSuite with BeforeAndAfter {
417417
}
418418
}
419419

420+
test("SSL RPC password propagation") {
421+
val conf = baseConf.clone()
422+
.set("spark.ssl.rpc.enabled", "true")
423+
.set("spark.ssl.rpc.keyStorePassword", "keyStorePass")
424+
.set("spark.ssl.rpc.keyPassword", "keyPass")
425+
.set("spark.ssl.rpc.privateKeyPassword", "privateKeyPass")
426+
.set("spark.ssl.rpc.trustStorePassword", "trustStorePass")
427+
428+
val step = new BasicExecutorFeatureStep(KubernetesTestConf.createExecutorConf(sparkConf = conf),
429+
new SecurityManager(conf), defaultProfile)
430+
431+
val executor = step.configurePod(SparkPod.initialPod())
432+
checkEnv(executor, conf, Map(
433+
SSLOptions.ENV_RPC_SSL_KEY_STORE_PASSWORD -> "keyStorePass",
434+
SSLOptions.ENV_RPC_SSL_KEY_PASSWORD -> "keyPass",
435+
SSLOptions.ENV_RPC_SSL_PRIVATE_KEY_PASSWORD -> "privateKeyPass",
436+
SSLOptions.ENV_RPC_SSL_TRUST_STORE_PASSWORD -> "trustStorePass"))
437+
}
438+
439+
test("SSL RPC passwords shouldn't propagate if RPC SSL is disabled") {
440+
val conf = baseConf.clone()
441+
.set("spark.ssl.rpc.enabled", "false")
442+
.set("spark.ssl.rpc.keyStorePassword", "keyStorePass")
443+
.set("spark.ssl.rpc.trustStorePassword", "trustStorePass")
444+
445+
val step = new BasicExecutorFeatureStep(KubernetesTestConf.createExecutorConf(sparkConf = conf),
446+
new SecurityManager(conf), defaultProfile)
447+
448+
val executor = step.configurePod(SparkPod.initialPod())
449+
SSLOptions.SPARK_RPC_SSL_PASSWORD_ENVS.foreach { env =>
450+
assert(!KubernetesFeaturesTestUtils.containerHasEnvVar(executor.container, env))
451+
}
452+
}
453+
454+
test("SSL RPC passwords shouldn't override an explicit secretKeyRef") {
455+
val conf = baseConf.clone()
456+
.set("spark.ssl.rpc.enabled", "true")
457+
.set("spark.ssl.rpc.keyStorePassword", "keyStorePass")
458+
.set("spark.ssl.rpc.trustStorePassword", "trustStorePass")
459+
460+
val step = new BasicExecutorFeatureStep(
461+
KubernetesTestConf.createExecutorConf(
462+
sparkConf = conf,
463+
secretEnvNamesToKeyRefs = Map(
464+
SSLOptions.ENV_RPC_SSL_KEY_STORE_PASSWORD -> "rpc-secret:keystore-password")),
465+
new SecurityManager(conf), defaultProfile)
466+
467+
val executor = step.configurePod(SparkPod.initialPod())
468+
checkEnv(executor, conf, Map(
469+
SSLOptions.ENV_RPC_SSL_TRUST_STORE_PASSWORD -> "trustStorePass"))
470+
}
471+
420472
test("SPARK-32661 test executor offheap memory") {
421473
baseConf.set(MEMORY_OFFHEAP_ENABLED, true)
422474
baseConf.set("spark.memory.offHeap.size", "42m")

0 commit comments

Comments
 (0)