前言
最近在提交 spark
程序到 yarn
消费 kerberos
认证方式的 kafka
数据。由于配置文件 相对/绝对路径不正确配置
遇到了报错,这里整理并记录一下。
环境信息
- spark 2.4
- hadoop 3.0
- kafka 2.4
问题原因:
先提前说下问题的最终原因:由于 spark-submit
提交任务命令 kafka_client_jaas.conf配置文件 相对/绝对路径 不合理导致
的。那么我原来的提交命令是什么
问题复现:
我们来重新复现下这个问题。之前用的错误的spark-submit
命令如下
spark-submit
命令行
spark-submit --class com.cebbank.rwms.SparkTest \
--principal "rwms@CDPCEBBANK.COM" \
--keytab "/user/rwms/rwms.keytab" \
--files "/etc/krb5.conf,/user/rwms/kafka_client_jaas.conf" \
--conf "spark.driver.extraJavaOptions=-Djava.security.auth.login.config=kafka_client_jaas.conf" \
--conf "spark.executor.extraJavaOptions=-Djava.security.auth.login.config=kafka_client_jaas.conf" \
--conf "spark.driver.memoryOverhead=1024" \
--conf "spark.executor.memoryOverhead=1024" \
--master yarn \
--deploy-mode cluster \
--name SparkTestDemo \
--driver-cores 1 \
--driver-memory 1G \
--executor-cores 1 \
--executor-memory 1G \
--queue rwms \
--num-executors 1 \
rwms-etl.jar
这里我用到如下几个配置文件:
- /etc/krb.conf
- kafka_client_jaas.conf
- rwms.keytab
并且这几个配置文件需要在 driver
节点和 executor
节点上都需要有。
kafka_client_jaas.conf
KafkaClient {com.sun.security.auth.module.Krb5LoginModule requireduseKeyTab=truekeyTab="/user/rwms/rwms.keytab"storeKey=trueuseTicketCache=falseserviceName="kafka"principal="rwms@CDPCEBBANK.COM";
};
报错内容
ERROR Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
org.apache.kafka.common.KafkaException: javax.security.auth.login.LoginException: Could not login: the client is being asked for a password, but the Kafka client code does not currently support obtaining a password from the user. not available to garner authentication information from the userat org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:160)at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:146)at org.apache.kafka.common.network.ChannelBuilders.serverChannelBuilder(ChannelBuilders.java:85)at kafka.network.Processor.<init>(SocketServer.scala:726)at kafka.network.SocketServer.newProcessor(SocketServer.scala:367)at kafka.network.SocketServer.$anonfun$addDataPlaneProcessors$1(SocketServer.scala:261)at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:158)at kafka.network.SocketServer.addDataPlaneProcessors(SocketServer.scala:260)at kafka.network.SocketServer.$anonfun$createDataPlaneAcceptorsAndProcessors$1(SocketServer.scala:223)at kafka.network.SocketServer.$anonfun$createDataPlaneAcceptorsAndProcessors$1$adapted(SocketServer.scala:220)at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)at kafka.network.SocketServer.createDataPlaneAcceptorsAndProcessors(SocketServer.scala:220)at kafka.network.SocketServer.startup(SocketServer.scala:120)at kafka.server.KafkaServer.startup(KafkaServer.scala:255)at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:38)at kafka.Kafka$.main(Kafka.scala:84)at kafka.Kafka.main(Kafka.scala)
使用 spark-local 模式
我们使用 spark on yarn-cluster
任务无法执行&#xff0c;于是我们将任务改为 spark local[*]
模式&#xff0c;发现就没问题。
问题解决
经过问题定位终于发现是 kafka_client_jaas.conf
中 keyTab&#61;"/user/rwms/rwms.keytab"
这一行的绝对路径导致的。
因为: keytab文件
和配置文件
是使用 YARN 资源分发。这些配置文件最终将位于 执行Spark YARN 容器的目录中&#xff0c;因此改行的内容应指定为相对路径 也就是 ./rwms.keytab
另外如下的几个配置也需要改成相对路径
--conf "spark.driver.extraJavaOptions&#61;-Djava.security.auth.login.config&#61;./kafka_client_jaas.conf"
--conf "spark.executor.extraJavaOptions&#61;-Djava.security.auth.login.config&#61;./kafka_client_jaas.conf"
spark.driver.extraJavaOptions
和 spark.executor.extraJavaOptions
都需要改成相对路径。
正确的kafka_client_jaas.conf
KafkaClient {com.sun.security.auth.module.Krb5LoginModule requireduseKeyTab&#61;truekeyTab&#61;"./rwms.keytab"storeKey&#61;trueuseTicketCache&#61;falseserviceName&#61;"kafka"principal&#61;"rwms&#64;CDPCEBBANK.COM";
};
这里我们以为问题已经解决了&#xff0c;结果还是不行&#xff0c;后面经过查询我们还需要将keytab 文件
也传递给 Yarn
服务。
最终的spark-submit命令
spark-submit \
--class com.cebbank.rwms.SparkTest \
--principal "rwms&#64;CDPCEBBANK.COM" \
--keytab "/user/rwms/k-rwms.keytab" \
--files "/etc/krb5.conf,/user/rwms/kafka_client_jaas.conf,/user/rwms/rwms.keytab" \
--conf "spark.driver.extraJavaOptions&#61;-Djava.security.auth.login.config&#61;./kafka_client_jaas.conf -Djava.security.krb5.conf&#61;/etc/krb5.conf" \
--conf "spark.executor.extraJavaOptions&#61;-Djava.security.auth.login.config&#61;./kafka_client_jaas.conf -Djava.security.krb5.conf&#61;/etc/krb5.conf" \
--conf "spark.driver.memoryOverhead&#61;1024" \
--conf "spark.executor.memoryOverhead&#61;1024" \
--master yarn \
--deploy-mode cluster \
--name SparkTestDemo \
--driver-cores 1 \
--driver-memory 1G \
--executor-cores 1 \
--executor-memory 1G \
--num-executors 1 \
--queue rwms \
rwms-etl.jar
为了方便阅读&#xff0c;这里我将不同的地方贴出
旧的命令行
--keytab "/user/rwms/k-rwms.keytab"
--files "/etc/krb5.conf,/user/rwms/kafka_client_jaas.conf"
新的命令行
--keytab "/user/rwms/k-rwms.keytab"
--files "/etc/krb5.conf,/user/rwms/kafka_client_jaas.conf,/user/rwms/rwms.keytab"
注意&#xff1a;新的命令行 keytab “/user/rwms/k-rwms.keytab” 这个地方特别注意下&#xff0c;文件名字是不同的&#xff0c;但是文件内容是一致的&#xff0c;为什么要这么改&#xff0c;是因为当同时配置 --keytab “/user/rwms/rwms.keytab” 和 – files “/user/rwms/rwms.keytab” 会造成程序的异常退出。为了避免冲突&#xff0c;我们引入一个不同名但同根的keytab 文件即&#xff1a;k-rwms.keytab 和 rwms.keytab 但其实这俩文件没什么区别。
举个例子&#xff1a;
当spark提交任务时&#xff0c;yarn会将--keytab
后面的keytab文件
与--files
里的文件先后上传&#xff0c;即 hdfs.keytab
与rwms.keytab
均会被上传&#xff0c;spark
与kafka
各取所需&#xff0c;即可正常工作。
当spark与kafka要使用相同的keytab文件时&#xff0c;比如都用rwms.keytab
&#xff0c;那么yarn会先后上传两次rwms.keytab
&#xff0c;在spark正使用的时候更新了keytab&#xff0c;造成异常退出。
下面列一下几种模式的不同&#xff1a;
spark locol 模式
在本地模式下&#xff0c;配置文件的相对/绝对路径&#xff0c;对程序没什么影响。
spark-yarn-client 模式
client 模式下&#xff0c;因为driver 端时在本地&#xff0c;本地的配置文件都有&#xff0c;所以spark.driver.extraJavaOptions
中的配置文件路径 相对/绝对 影响不大&#xff0c;spark.executor.extraJavaOptions
需要写成相对路径。
spark-yarn-cluster 模式
cluster模式下&#xff0c;driver 和 executor
节点都不在本地&#xff0c;所以配置文件都不存在&#xff0c;所以spark.driver.extraJavaOptions
需要写成相对路径&#xff0c;
spark.executor.extraJavaOptions
需要写成相对路径。
总结
以上的问题&#xff0c;说白了就是在任务真正的执行节点&#xff0c;并没有成功从 绝对路径
中加载到对应的配置文件。
我们在生产中将 jaas 配置文件和 keytab 作为本地资源文件传递。将 jaas
配置文件选项添加到为驱动程序和执行程序指定的 JVM
选项中
因为别的节点并没有这些配置文件。所以需要用 --flies
将我们需要用到的配置都加载到yarn
服务上&#xff0c;然后 yarn
来将这些配置问价分发到真正执行任务的目录上。
我们生产上使用的一些参数中指定的配置也最好写成相对路径
。如&#xff1a;spark.driver.extraJavaOptions
和 spark.executor.extraJavaOptions
。
参考
- https://docs.cloudera.com/HDPDocuments/HDP2/HDP-2.4.3/bk_spark-guide/content/spark-streaming-kafka-kerb.html
- https://blog.csdn.net/u012373717/article/details/115401706