首先,我想说的是,我看到的唯一解决这个问题的方法是:Spark 1.6.1 SASL。然而,当添加用于火花和纱线身份验证的配置时,它仍然不起作用。以下是我在亚马逊emr:上的纱线集群上使用spark提交的spark配置
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");
注意,我在代码中向sparkContext的hadoop配置添加了spark.authenticate,而不是core-site.xml(我认为我可以做到这一点,因为其他东西也可以)。
看这里:https://github.com/apache/spark/blob/master/common/network-yarn/src/main/java/org/apache/spark/network/yarn/YarnShuffleService.java看起来两者都有火花。身份验证是必要的。当我运行这个应用程序时,我会得到以下堆栈跟踪。
03年1月17日22:10:23信息存储。BlockManager:向本地外部shuffle服务注册执行器。03年1月17日22:10:23错误客户端。TransportClientFactory:178毫秒后引导客户端时出现异常java.lang.RuntimeException:java.lang.IollegalArgumentException:未知消息类型:-22网址:org.apache.spark.network.shuffle.procol.BlockTransferMessage$Decoder.fromByteBuffer(BlockTransferMessage.java:67)网址:org.apache.spark.network.shuffle.ExternalShuffleBlockHandler.receive(ExternalShuffleBlock Handler.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.nety.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInoundHandler.java:105)位于io.netty.channe.AbstractChannelHandlerContext.invokeChannelRead(AbstractchannelHandlerContent.java:333)位于io.nety.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandler Content.java:319)在io.netty.handler.timeout.IidleStateHandler.channelRead(IdleStateHandler.java:254)位于io.netty.channe.AbstractChannelHandlerContext.invokeChannelRead(AbstractchannelHandlerContent.java:333)位于io.nety.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandler Content.java:319)位于io.nety.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)位于io.netty.channe.AbstractChannelHandlerContext.invokeChannelRead(AbstractchannelHandlerContent.java:333)位于io.nety.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandler Content.java:319)网址:org.apache.spark.network.util.TransportFrameDecoder.channelRead(TransportFrameDecoder.java:86)位于io.netty.channe.AbstractChannelHandlerContext.invokeChannelRead(AbstractchannelHandlerContent.java:333)位于io.nety.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandler Content.java:319)位于io.netty.channe.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)位于io.nety.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:130)位于io.nety.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)位于io.nety.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)位于io.nety.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)位于io.nety.channel.nio.NioEventLoop.run(NioEventLoop.java:354)位于io.nety.util.concurrent.SingleThreadEventExecutiator$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工作?我是否遗漏了某个地方记录的明显内容?
所以我终于弄明白了。上一个StackOverflow线程在技术上是正确的。我需要将spark.authenticate添加到纱线配置中。也许这样做是可能的,但我不知道如何在代码中添加这种配置,这在高层是有道理的,为什么会出现这种情况。我会在下面发布我的配置,以防将来有人遇到这个问题。
首先,我使用了一个aws-emr配置文件(例如使用aws-cliaws 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"
}
}]
在添加Spark网络加密的配置选项后,我在Dataproc(谷歌云平台)上的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验证了加密。我在主节点上安装了如下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
来实现。