6

我正在向连接到安全 hbase 集群的 YARN(在 spark 2.1.1 + kafka 0.10.2.1 上)提交作业。当我在“本地”模式下运行时(spark.master=local[*]),这项工作表现得很好。

但是,一旦我将 master 作为 YARN(并将部署模式作为客户端)提交作业,我就会看到以下错误消息 -

Caused by: javax.security.auth.login.LoginException: Unable to obtain password from user

我正在关注 hortonworks 建议,以向纱线集群提供有关 HBase 和 keytab 等的信息。关注这篇 kb 文章 - https://community.hortonworks.com/content/supportkb/48988/how-to-run-spark-job-to -interact-with-secured-hbas.html

任何指针可能会发生什么?

登录HBase的机制:

UserGroupInformation.setConfiguration(hbaseConf)
val keyTab = "keytab-location") 
val principal = "kerberos-principal"
val ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal, keyTab)
UserGroupInformation.setLoginUser(ugi)
ugi.doAs(new PrivilegedExceptionAction[Void]() {

override def run: Void = {
  hbaseCon = Some(ConnectionFactory.createConnection(hbaseConf))
  null
}
})

另外,我尝试了另一种登录机制,如:

UserGroupInformation.loginUserFromKeytab(principal, keyTab)
connection=ConnectionFactory.createConnection(hbaseConf)

请建议。

4

1 回答 1

14

在寻求从 Spark 到 HBase 的 Kerberos 身份验证过程中,您并不孤单,参见。SPARK-12279

一个鲜为人知的事实是,Spark 现在会在启动时为 Yarn、HDFS、Hive、HBase生成Hadoop“身份验证令牌”。然后将这些令牌广播给执行程序,这样他们就不必再与 Kerberos auth、keytabs 等混淆。

第一个问题是它没有明确记录,如果失败,默认情况下会隐藏错误(即大多数人不使用 Kerberos 连接到 HBase,因此声明 HBase JAR 不在 CLASSPATH 中通常是没有意义的,并且没有创建 HBase 令牌...通常。)
要记录有关这些令牌的所有详细信息,您必须将日志级别设置为org.apache.spark.deploy.yarn.ClientDEBUG。

第二个问题是,除了属性之外,Spark 还支持许多 env 变量,有些已记录,有些未记录,有些实际上已弃用。
例如,SPARK_CLASSPATH现在已弃用,其内容实际上注入到 Spark 属性spark.driver/spark.executor.extraClassPath中。
SPARK_DIST_CLASSPATH仍在使用中,例如在 Cloudera 发行版中,它用于将核心 Hadoop 库和配置注入 Spark“启动器”,以便它可以在驱动程序启动之前引导 YARN 集群执行(即之前spark.driver.extraClassPath被评估)。
其他感兴趣的变量是

  • HADOOP_CONF_DIR
  • SPARK_CONF_DIR
  • SPARK_EXTRA_LIB_PATH
  • SPARK_SUBMIT_OPTS
  • SPARK_PRINT_LAUNCH_COMMAND

第三个问题是,在某些特定情况下(例如 Cloudera 发行版中的 YARN-cluster 模式),Spark 属性spark.yarn.tokens.hbase.enabled被静默设置为false——这绝对没有意义,该默认值true在 Spark 源代码中是硬编码的。 .!
所以建议你true在你的工作配置中明确地强制它。

第四个问题是,即使在启动时已经创建了 HBase 令牌,执行程序也必须显式使用它来进行身份验证。幸运的是,Cloudera 为 HBase 提供了一个“Spark 连接器”,可以自动处理这种讨厌的东西。它现在是 HBase 客户端的一部分,默认情况下(参见hbase-spark*.jar)。

第五个问题是,AFAIK,如果您metrics-core*.jar在 CLASSPATH 中没有,那么 HBase 连接将失败,并出现令人费解的(和不相关的)ZooKepper 错误。


¤¤¤¤¤如何使用调试跟踪使这些东西工作

# we assume that spark-env.sh and spark-default.conf are already Hadoop-ready,
# and also *almost* HBase-ready (as in a CDH distro);
# especially HADOOP_CONF_DIR and SPARK_DIST_CLASSPATH are expected to be set
# but spark.*.extraClassPath / .extraJavaOptions are expected to be unset

KRB_DEBUG_OPTS="-Dlog4j.logger.org.apache.spark.deploy.yarn.Client=DEBUG -Dlog4j.logger.org.apache.hadoop.hbase.zookeeper.RecoverableZooKeeper=DEBUG -Dlog4j.logger.org.apache.hadoop.hbase.client.ConnectionManager$HConnectionImplementation=DEBUG -Dlog4j.logger.org.apache.hadoop.hbase.spark.HBaseContext=DEBUG -Dsun.security.krb5.debug=true -Djava.security.debug=gssloginconfig,configfile,configparser,logincontext"
EXTRA_HBASE_CP=/etc/hbase/conf/:/opt/cloudera/parcels/CDH/lib/hbase/hbase-spark.jar:/opt/cloudera/parcels/CDH/lib/hbase/lib/metrics-core-2.2.0.jar

export SPARK_SUBMIT_OPTS="$KRB_DEBUG_OPTS"
export HADOOP_JAAS_DEBUG=true
export SPARK_PRINT_LAUNCH_COMMAND=True

spark-submit --master yarn-client \
  --files "/etc/spark/conf/log4j.properties#yarn-log4j.properties" \
  --principal XX@Z.NET --keytab /a/b/XX.keytab \
  --conf spark.yarn.tokens.hbase.enabled=true \
  --conf spark.driver.extraClassPath=$EXTRA_HBASE_CP \
  --conf spark.executor.extraClassPath=$EXTRA_HBASE_CP \
  --conf "spark.executor.extraJavaOptions=$KRB_DEBUG_OPTS -Dlog4j.configuration=yarn-log4j.properties" \
  --conf spark.executorEnv.HADOOP_JAAS_DEBUG=true \
  --class TestSparkHBase  TestSparkHBase.jar

spark-submit --master yarn-cluster --conf spark.yarn.report.interval=4000 \
  --files "/etc/spark/conf/log4j.properties#yarn-log4j.properties" \
  --principal XX@Z.NET --keytab /a/b/XX.keytab \
  --conf spark.yarn.tokens.hbase.enabled=true \
  --conf spark.driver.extraClassPath=$EXTRA_HBASE_CP \
  --conf "spark.driver.extraJavaOptions=$KRB_DEBUG_OPTS -Dlog4j.configuration=yarn-log4j.properties" \
  --conf spark.driverEnv.HADOOP_JAAS_DEBUG=true \
  --conf spark.executor.extraClassPath=$EXTRA_HBASE_CP \
  --conf "spark.executor.extraJavaOptions=$KRB_DEBUG_OPTS -Dlog4j.configuration=yarn-log4j.properties" \
  --conf spark.executorEnv.HADOOP_JAAS_DEBUG=true \
  --class TestSparkHBase  TestSparkHBase.jar

PS:当在执行器的 CLASSPATH 中使用HBaseContext不需要的时,conf 会自动传播。/etc/hbase/conf/

PPS:我建议你设置log4j.logger.org.apache.zookeeper.ZooKeeper=WARNlog4j.properties因为它冗长、无用,甚至令人困惑(所有有趣的东西都记录在 HBase 级别)

SPARK_SUBMIT_OPTSPPS:您还可以静态列出 Log4J 选项,而不是那个冗长的var,$SPARK_CONF_DIR/log4j.properties其余选项在$SPARK_CONF_DIR/java-opts; 中的 Spark 属性$SPARK_CONF_DIR/spark-defaults.conf和 env 变量也是如此$SPARK_CONF_DIR/spark-env.sh


¤¤¤¤¤关于 HBase 的“Spark 连接器”

摘自HBase 官方文档,第 83 章Basic Spark

所有 Spark 和 HBase 集成的根源是HBaseContext. HBaseContext接收 HBase 配置并将它们推送到 Spark 执行器。这允许我们在静态位置为每个 Spark Executor 建立一个 HBase 连接。

文档中没有提到的是HBaseContext自动使用 HBase“身份验证令牌”(如果存在)来验证执行者。

另请注意,该文档有foreachPartition一个 RDD 上的 Spark 操作示例(在 Scala 中,然后在 Java 中),使用BufferedMutator异步批量加载到 HBase。

于 2017-05-31T16:51:31.950 回答