首先,我想说的是,我所看到的唯一解决此问题的方法是:Spark 1.6.1 SASL。但是,在添加spark和yarn认证的配置时,它仍然无法正常工作。下面是我在amazon' s emr上使用spark-submit进行火花提交的火花配置:
SparkConf sparkConf = new SparkConf().setAppName("secure-test");
sparkConf.set("spark.authenticate.enableSaslEncryption", "true");
sparkConf.set("spark.network.sasl.serverAlwaysEncrypt", "true");
sparkConf.set("spark.authenticate", "true");
sparkConf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
sparkConf.set("spark.kryo.registrator", "org.nd4j.Nd4jRegistrator");
try {
sparkConf.registerKryoClasses(new Class<?>[]{
Class.forName("org.apache.hadoop.io.LongWritable"),
Class.forName("org.apache.hadoop.io.Text")
});
} catch (Exception e) {}
sparkContext = new JavaSparkContext(sparkConf);
sparkContext.hadoopConfiguration().set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem");
sparkContext.hadoopConfiguration().set("fs.s3a.enableServerSideEncryption", "true");
sparkContext.hadoopConfiguration().set("spark.authenticate", "true");
注意,我在代码中将spark.authenticate添加到sparkContext的hadoop配置而不是core-site.xml(我假设我可以这样做,因为其他的东西也可以工作)。
看这里:https://github.com/apache/spark/blob/master/common/network-yarn/src/main/java/org/apache/spark/network/yarn/YarnShuffleService.java似乎两个spark.authenticate都是必要的。当我运行此应用程序时,我得到以下堆栈跟踪。
17/01/03 22:10:23 INFO storage.BlockManager:使用本地外部shuffle服务注册执行程序。 17/01/03 22:10:23 ERROR client.TransportClientFactory:在178 ms后自举引导客户端时发生异常 java.lang.RuntimeException:java.lang.IllegalArgumentException:未知消息类型:-22 at org.apache.spark.network.shuffle.protocol.BlockTransferMessage $ Decoder.fromByteBuffer(BlockTransferMessage.java:67) 在org.apache.spark.network.shuffle.ExternalShuffleBlockHandler.receive(ExternalShuffleBlockHandler.java:71) 在org.apache.spark.network.server.TransportRequestHandler.processRpcRequest(TransportRequestHandler.java:149) 在org.apache.spark.network.server.TransportRequestHandler.handle(TransportRequestHandler.java:102) 在org.apache.spark.network.server.TransportChannelHandler.channelRead0(TransportChannelHandler.java:104) 在org.apache.spark.network.server.TransportChannelHandler.channelRead0(TransportChannelHandler.java:51) 在io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) 在io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:254) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) 在org.apache.spark.network.util.TransportFrameDecoder.channelRead(TransportFrameDecoder.java:86) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) 在io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) at io.netty.channel.nio.AbstractNioByteChannel $ NioByteUnsafe.read(AbstractNioByteChannel.java:130) 在io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468) 在io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382) 在io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) at io.netty.util.concurrent.SingleThreadEventExecutor $ 2.run(SingleThreadEventExecutor.java:116) 在java.lang.Thread.run(Thread.java:745)
在Spark的文档中,它说
For Spark on YARN deployments, configuring spark.authenticate to true will automatically handle generating and distributing the shared secret. Each application will use a unique shared secret.
根据上面的纱线文件中的评论,这似乎是错误的,但是在拍摄失败的情况下,我仍然迷失在应该让sasl工作的地方?我是否遗漏了某些明显记录的内容?
答案 0 :(得分:1)
所以我终于明白了。之前的StackOverflow线程在技术上是正确的。我需要将spark.authenticate添加到纱线配置中。也许有可能做到这一点,但我无法弄清楚如何在代码中添加这种配置,这在很高的层次上是有道理的。我将在下面发布我的配置,以防其他人在将来遇到此问题。
首先,我使用了一个aws emr配置文件(这个例子就是当使用aws cli aws emr create-cluster --configurations file://youpathhere.json
时)
然后,我将以下json添加到文件中:
[{
"Classification": "spark-defaults",
"Properties": {
"spark.authenticate": "true",
"spark.authenticate.enableSaslEncryption": "true",
"spark.network.sasl.serverAlwaysEncrypt": "true"
}
},
{
"Classification": "core-site",
"Properties": {
"spark.authenticate": "true"
}
}]
答案 1 :(得分:0)
在我为 Spark 网络加密添加配置选项后,我在 Dataproc (Google Cloud Platform) 上的 Spark 上收到了相同的错误消息。
我最初使用以下命令创建了 Dataproc 集群。
gcloud dataproc clusters create test-encryption --no-address \
--service-account=<SERVICE-ACCOUNT> \
--zone=europe-west3-c --region=europe-west3 \
--subnet=<SUBNET> \
--properties 'spark:spark.authenticate=true,spark:spark.network.crypto.enabled=true'
解决方案是另外添加配置 'yarn:spark.authenticate=true'
。因此,可以按如下方式创建具有 Spark RPC 加密的工作 Dataproc 集群。
gcloud dataproc clusters create test-encryption --no-address \
--service-account=<SERVICE-ACCOUNT> \
--zone=europe-west3-c --region=europe-west3 \
--subnet=<SUBNET> \
--properties 'spark:spark.authenticate=true,spark:spark.network.crypto.enabled=true,yarn:spark.authenticate=true'
我使用 ngrep 验证了加密。我在master节点上安装ngrep如下。
sudo apt-get update
sudo apt-get install ngrep
然后我在任意端口 20001 上运行 ngrep。
sudo ngrep port 20001
如果您随后运行具有以下配置属性的 Spark 作业,您可以看到驱动程序和工作程序节点之间的加密通信。
spark.driver.port=20001
spark.blockManager.port=20002
注意,我总是建议在 Dataproc 上启用 Kerberos 以保护 Hadoop、Yarn 等的身份验证。这可以通过集群创建命令中的标志 --enable-kerberos
来实现。