从Spark访问Hdfs会产生令牌缓存错误无法获取主Kerberos主体以用作续订

时间:2014-04-23 08:08:16

标签: authentication hadoop kerberos apache-spark

我试图运行测试Spark脚本以便将Spark连接到hadoop。 该脚本如下

from pyspark import SparkContext

sc = SparkContext("local", "Simple App")
file = sc.textFile("hdfs://hadoop_node.place:9000/errs.txt")
errors = file.filter(lambda line: "ERROR" in line)
errors.count()

当我用pyspark运行时,我得到了

  

py4j.protocol.Py4JJavaError:调用时发生错误   o21.collect。 :java.io.IOException:无法获得Master Kerberos   用作续订的委托人           在org.apache.hadoop.mapreduce.security.TokenCache.obtainTokensForNamenodesInternal(TokenCache.java:116)           at org.apache.hadoop.mapreduce.security.TokenCache.obtainTokensForNamenodesInternal(TokenCache.java:100)           at org.apache.hadoop.mapreduce.security.TokenCache.obtainTokensForNamenodes(TokenCache.java:80)           在org.apache.hadoop.mapred.FileInputFormat.listStatus(FileInputFormat.java:187)           在org.apache.hadoop.mapred.FileInputFormat.getSplits(FileInputFormat.java:251)           在org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:140)           在org.apache.spark.rdd.RDD $$ anonfun $ partitions $ 2.apply(RDD.scala:207)           在org.apache.spark.rdd.RDD $$ anonfun $ partitions $ 2.apply(RDD.scala:205)           在scala.Option.getOrElse(Option.scala:120)           在org.apache.spark.rdd.RDD.partitions(RDD.scala:205)           在org.apache.spark.rdd.MappedRDD.getPartitions(MappedRDD.scala:28)           在org.apache.spark.rdd.RDD $$ anonfun $ partitions $ 2.apply(RDD.scala:207)           在org.apache.spark.rdd.RDD $$ anonfun $ partitions $ 2.apply(RDD.scala:205)           在scala.Option.getOrElse(Option.scala:120)           在org.apache.spark.rdd.RDD.partitions(RDD.scala:205)           在org.apache.spark.api.python.PythonRDD.getPartitions(PythonRDD.scala:46)           在org.apache.spark.rdd.RDD $$ anonfun $ partitions $ 2.apply(RDD.scala:207)           在org.apache.spark.rdd.RDD $$ anonfun $ partitions $ 2.apply(RDD.scala:205)           在scala.Option.getOrElse(Option.scala:120)           在org.apache.spark.rdd.RDD.partitions(RDD.scala:205)           在org.apache.spark.SparkContext.runJob(SparkContext.scala:898)           在org.apache.spark.rdd.RDD.collect(RDD.scala:608)           在org.apache.spark.api.java.JavaRDDLike $ class.collect(JavaRDDLike.scala:243)           在org.apache.spark.api.java.JavaRDD.collect(JavaRDD.scala:27)           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)           at java.lang.reflect.Method.invoke(Method.java:606)           在py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:231)           在py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:379)           在py4j.Gateway.invoke(Gateway.java:259)           at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)           在py4j.commands.CallCommand.execute(CallCommand.java:79)           在py4j.GatewayConnection.run(GatewayConnection.java:207)           在java.lang.Thread.run(Thread.java:744)

尽管有事实

,但仍然会发生这种情况
  • 我做了一个kinit,一个klist显示我有正确的令牌
  • 当我发出./bin/hadoop fs -ls hdfs://hadoop_node.place:9000 / errs.txt 它显示文件
  • 本地hadoop客户端和spark都具有相同的配置文件

spark / conf和hadoop / conf文件夹中的core-site.xml如下所示 (从其中一个hadoop节点获得)

<configuration>
    <property>

        <name>hadoop.security.auth_to_local</name>
        <value>
            RULE:[1:$1](.*@place)s/@place//
            RULE:[2:$1/$2@$0](.*/node1.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node2.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node3.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node4.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node5.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node6.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:$1/$2@$0](.*/node7.place@place)s/^([a-zA-Z]*).*/$1/
            RULE:[2:nobody]
            DEFAULT
        </value>
    </property>
    <property>
        <name>net.topology.node.switch.mapping.impl</name>
        <value>org.apache.hadoop.net.TableMapping</value>
    </property>
    <property>
        <name>net.topology.table.file.name</name>
        <value>/etc/hadoop/conf/topology.table.file</value>
    </property>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://server.place:9000/</value>
    </property>
    <property>
      <name>hadoop.security.authentication</name>
      <value>kerberos</value>
    </property>

    <property>
      <name>hadoop.security.authorization</name>
      <value>true</value>
    </property>

    <property>
      <name>hadoop.proxyuser.hive.hosts</name>
      <value>*</value>
    </property>

    <property>
      <name>hadoop.proxyuser.hive.groups</name>
      <value>*</value>
    </property>

</configuration>

有人可以指出我错过了什么吗?

1 个答案:

答案 0 :(得分:5)

创建我自己的hadoop集群后,为了更好地理解hadoop如何工作。我修好了。

您必须为Spark提供一个有效的.keytab文件,该文件是为至少具有hadoop集群读取权限的帐户生成的。

此外,您必须使用hdfs集群的hdfs-site.xml提供spark。

因此,对于我的情况,我必须在运行

时创建一个keytab文件
  

klist -k -e -t

就可以获得如下条目

  

host/fully.qualified.domain.name@REALM.COM

在我的情况下,主机是文字主机而不是变量。 同样在你的hdfs-site.xml中,你必须提供keytab文件的路径并说出

  

host/_HOST@REALM.COM

将是您的帐户。

Cloudera有一篇关于如何做的非常详细的文章。

修改 在玩了一些不同的配置后,我认为应该注意以下几点。 您必须使用hadoop集群的确切hdfs-site.xml和core-site.xml提供spark。否则它不会工作