k8s上的Apache Spark:无法保护驱动程序和执行程序之间的RPC通信

时间:2018-12-11 08:50:47

标签: apache-spark kubernetes

我一直在尝试在k8s上部署Spark 2.4,并希望在驱动程序和执行程序之间建立安全的RPC通信通道。在spark-submit

中使用了以下配置参数
spark.authenticate true
spark.authenticate.secret good
spark.network.crypto.enabled true
spark.network.crypto.keyFactoryAlgorithm PBKDF2WithHmacSHA1
spark.network.crypto.saslFallback false

驱动程序和执行程序无法在安全通道上进行通信,并引发以下错误。

Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1713)
        at org.apache.spark.deploy.SparkHadoopUtil.runAsSparkUser(SparkHadoopUtil.scala:64)
        at org.apache.spark.executor.CoarseGrainedExecutorBackend$.run(CoarseGrainedExecutorBackend.scala:188)
        at org.apache.spark.executor.CoarseGrainedExecutorBackend$.main(CoarseGrainedExecutorBackend.scala:281)
        at org.apache.spark.executor.CoarseGrainedExecutorBackend.main(CoarseGrainedExecutorBackend.scala)
Caused by: org.apache.spark.SparkException: Exception thrown in awaitResult:
        at org.apache.spark.util.ThreadUtils$.awaitResult(ThreadUtils.scala:226)
        at org.apache.spark.rpc.RpcTimeout.awaitResult(RpcTimeout.scala:75)
        at org.apache.spark.rpc.RpcEnv.setupEndpointRefByURI(RpcEnv.scala:101)
        at org.apache.spark.executor.CoarseGrainedExecutorBackend$$anonfun$run$1.apply$mcV$sp(CoarseGrainedExecutorBackend.scala:201)
        at org.apache.spark.deploy.SparkHadoopUtil$$anon$2.run(SparkHadoopUtil.scala:65)
        at org.apache.spark.deploy.SparkHadoopUtil$$anon$2.run(SparkHadoopUtil.scala:64)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1698)
        ... 4 more
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: Unknown challenge message.
        at org.apache.spark.network.crypto.AuthRpcHandler.receive(AuthRpcHandler.java:109)
        at org.apache.spark.network.server.TransportRequestHandler.processRpcRequest(TransportRequestHandler.java:181)
        at org.apache.spark.network.server.TransportRequestHandler.handle(TransportRequestHandler.java:103)
        at org.apache.spark.network.server.TransportChannelHandler.channelRead(TransportChannelHandler.java:118)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)

有人可以指导我吗?

1 个答案:

答案 0 :(得分:0)

免责声明:我对Spark实施没有很深入的了解,因此,在使用下面介绍的解决方法时要小心。

AFAIK,Spark在2.4.0版本中不支持k8的身份验证/加密。

有一张票已经确定,可能会在下一个Spark版本中发布:https://issues.apache.org/jira/browse/SPARK-26239

问题在于,火花执行器尝试打开与驱动程序的连接,并且仅使用该连接发送配置。虽然,执行程序使用默认配置创建连接,并且系统属性以“ spark”开头。 作为参考,这里是执行者打开连接的地方:https://github.com/apache/spark/blob/5fa4384/core/src/main/scala/org/apache/spark/executor/CoarseGrainedExecutorBackend.scala#L201

理论上,如果您设置spark.executor.extraJavaOptions=-Dspark.authenticate=true -Dspark.network.crypto.enabled=true ...,它会有所帮助,尽管驱动程序会检查extraJavaOptions中没有设置火花参数。

尽管有一种解决方法(有点hacky):您可以设置spark.executorEnv.JAVA_TOOL_OPTIONS=-Dspark.authenticate=true -Dspark.network.crypto.enabled=true ...。 Spark不会检查此参数,但是JVM使用此env变量将此参数添加到属性中。

此外,我建议不要使用JAVA_TOOL_OPTIONS来传递密码,而应该使用spark.executorEnv._SPARK_AUTH_SECRET=<secret>