【spark】记录一次 spark sparkstreaming 使用命令行提交任务在Yarn集群模式无法正常消费kerberos kafka数据的问题

前言

最近在提交 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.test.SparkTest \
--principal "test@TEST.COM" \
--keytab "/user/test/test.keytab" \
--files "/etc/krb5.conf,/user/test/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 test \
--num-executors 1 \
test-etl.jar

这里我用到如下几个配置文件:

  1. /etc/krb.conf
  2. kafka_client_jaas.conf
  3. test.keytab

并且这几个配置文件需要在 driver 节点和 executor 节点上都需要有。

kafka_client_jaas.conf

KafkaClient {
   com.sun.security.auth.module.Krb5LoginModule required
   useKeyTab=true
   keyTab="/user/test/test.keytab"
   storeKey=true
   useTicketCache=false
   serviceName="kafka"
   principal="test@TEST.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 user
        at 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 任务无法执行,于是我们将任务改为 spark local[*] 模式,发现就没问题。

问题解决

经过问题定位终于发现是 kafka_client_jaas.confkeyTab="/user/test/test.keytab" 这一行的绝对路径导致的。

因为: keytab文件配置文件是使用 YARN 资源分发。这些配置文件最终将位于 执行Spark YARN 容器的目录中,因此改行的内容应指定为相对路径 也就是 ./test.keytab

另外如下的几个配置也需要改成相对路径

--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"

spark.driver.extraJavaOptionsspark.executor.extraJavaOptions 都需要改成相对路径。

正确的kafka_client_jaas.conf

KafkaClient {
   com.sun.security.auth.module.Krb5LoginModule required
   useKeyTab=true
   keyTab="./test.keytab"
   storeKey=true
   useTicketCache=false
   serviceName="kafka"
   principal="test@TEST.COM";
};

这里我们以为问题已经解决了,结果还是不行,后面经过查询我们还需要将keytab 文件也传递给 Yarn 服务。

最终的spark-submit命令

spark-submit \
--class com.test.SparkTest \
--principal "test@TEST.COM" \
--keytab "/user/test/k-test.keytab" \
--files "/etc/krb5.conf,/user/test/kafka_client_jaas.conf,/user/test/test.keytab" \
--conf "spark.driver.extraJavaOptions=-Djava.security.auth.login.config=./kafka_client_jaas.conf -Djava.security.krb5.conf=/etc/krb5.conf" \
--conf "spark.executor.extraJavaOptions=-Djava.security.auth.login.config=./kafka_client_jaas.conf -Djava.security.krb5.conf=/etc/krb5.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 \
--num-executors 1 \
--queue test \
test-etl.jar

为了方便阅读,这里我将不同的地方贴出

旧的命令行
--keytab "/user/test/k-test.keytab"
--files "/etc/krb5.conf,/user/test/kafka_client_jaas.conf"
新的命令行
--keytab "/user/test/k-test.keytab" 
--files "/etc/krb5.conf,/user/rwms/kafka_client_jaas.conf,/user/test/test.keytab"

注意:新的命令行 keytab “/user/test/k-test.keytab” 这个地方特别注意下,文件名字是不同的,但是文件内容是一致的,为什么要这么改,是因为当同时配置 --keytab “/user/test/test.keytab” 和 – files “/user/test/test.keytab” 会造成程序的异常退出。为了避免冲突,我们引入一个不同名但同根的keytab 文件即:k-test.keytab 和 test.keytab 但其实这俩文件没什么区别。

举个例子:
当spark提交任务时,yarn会将--keytab后面的keytab文件--files里的文件先后上传,即 hdfs.keytabrwms.keytab均会被上传,sparkkafka各取所需,即可正常工作。

当spark与kafka要使用相同的keytab文件时,比如都用rwms.keytab,那么yarn会先后上传两次rwms.keytab,在spark正使用的时候更新了keytab,造成异常退出。

下面列一下几种模式的不同:

spark locol 模式
在本地模式下,配置文件的相对/绝对路径,对程序没什么影响。

spark-yarn-client 模式
client 模式下,因为driver 端时在本地,本地的配置文件都有,所以spark.driver.extraJavaOptions 中的配置文件路径 相对/绝对 影响不大,spark.executor.extraJavaOptions 需要写成相对路径。

spark-yarn-cluster 模式
cluster模式下,driver 和 executor 节点都不在本地,所以配置文件都不存在,所以spark.driver.extraJavaOptions 需要写成相对路径,
spark.executor.extraJavaOptions 需要写成相对路径。

总结

以上的问题,说白了就是在任务真正的执行节点,并没有成功从 绝对路径 中加载到对应的配置文件。

我们在生产中将 jaas 配置文件和 keytab 作为本地资源文件传递。将 jaas 配置文件选项添加到为驱动程序和执行程序指定的 JVM 选项中

因为别的节点并没有这些配置文件。所以需要用 --flies 将我们需要用到的配置都加载到yarn 服务上,然后 yarn 来将这些配置问价分发到真正执行任务的目录上。

我们生产上使用的一些参数中指定的配置也最好写成相对路径。如:spark.driver.extraJavaOptionsspark.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
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值