spark streaming 在kerberos认证后的集群上提交任务
背景
集群有kerberos认证,spark批处理任务提交后正常运行,spark streaming/structed streaming 任务提交后运行不了,报 java.io.IOException: org.apache.hadoop.security.AccessControlException: Client cannot authenticate via:[TOKEN, KERBEROS] 的错误,其中streaming任务里面有用到sparkSQL
处理方式
找到多种处理方式,在一一尝试之后,均不起作用。后突然灵光一闪,成功解决,现将所有方法罗列如下
前置条件
1、在提交spark-submit之前,确保要有SPARK_HOME,没有则需要export一下。
2、尽量打源码包,不要把依赖都打到包里,在提交的时候使用–jars提交集群上没有的依赖,避免开发环境和集群环境所用的同名依赖不同引起问题。
方法一:在提交命令里面增加参数
此方法网上有很多样例,此处直接列出增加的参数
–keytab /xxx/xxx/username.keytab --principal username@XXX.com
网上很多说法是把提交用户的principal 和keytab 增加到参数里面即可,其他都不用管,程序会自动进行认证,类似的还有 --conf spark.yarn.principal=username@XXX.com --conf spark.yarn.keytab=/xxx/xxx/username.keytab
此方法可以一试,我这里环境实测无效
方法二:在代码里面用UGI进行认证
代码如下
// 增加kerberos认证测试
logger.info(“=before Kerberos auth driver==”)
System.setProperty(“java.security.krb5.conf”, “krb5.conf”)
val principal = “username”
val keytabPath = “username.keytab”
val hadoopConf = new Configuration()
hadoopConf.set(“hadoop.security.authentication”, “Kerberos”)
UserGroupInformation.setConfiguration(hadoopConf)
UserGroupInformation.loginUserFromKeytab(principal, keytabPath)
logger.info(“=after Kerberos auth driver==”)
此方法本人环境测试无效。只能实现在driver中成功认证,executor中不能认证。
备注一:Unable to obtain password for user
此方法可能报 failure to login: for principle :uxername from username.keytab Unable to obtain password for user
由于 UserGroupInformation 只会从本地地址中获取keytab信息,所以不能填写hdfs目录,建议用相对路径,或者直接填keytab的文件名即可,然后再提交命令里面用–file 参数将 krb5.conf 和keytab文件传上去。
小贴士:在参数里面用了–keytab /xxx/xxx/username.keytab --principal username@XXX.com 之后,在用–file无法提交keytab 文件
此时只要将keytab文件改个名字即可,例如将 username.keytab 改为username_1.keytab就行。因为使用–keytab /xxx/xxx/username.keytab 之后,spark-submit 会将keytab 也上传至spark的运行路径下,导致再上传keytab 文件就报同名文件的错误,且用 --keytab 参数后,提交至spark运行路径下的keytab文件会被改名为username.keytab-{$md5},导致直接程序中获取不到username.keytab文件,所以这里改个名字就行。
备注二:在做了HA的CDH集群上使用此方法时,需注意如下要点
spark的checkpoint或者所写的hdfs路径,要使用逻辑URI,不能使用实际节点名
即得用类似hdfs://nameservice1/ 的连接,而不能使用类似hdfs://cdh01:8020/ 的连接原因如下:
在使用UGI进行登录注册认证时,如果它找到一个namenode uri 而不是逻辑uri,那么它将创建非HA文件系统,该文件系统将尝试使用简单UGI而不是kerberos UGI
源码:
private static Configuration getHdfsConfiguration() throws IOException {
Configuration configuration = new Configuration();
configuration.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName());
configuration.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
File hadoopCoreConfig = new File(CONF_CORE_SITE);
File hadoopHdfsConfig = new File(CONF_HDFS_SITE);
if (! hadoopCoreConfig.exists() || ! hadoopHdfsConfig.exists()) {
throw new FileNotFoundException("Files core-site.xml or hdfs-site.xml are not found. Check /etc/hadoop/conf/ path.");
}
configuration.addResource(new Path(hadoopCoreConfig.toURI()));
configuration.addResource(new Path(hadoopHdfsConfig.toURI()));
//Use existing security context created by $ kinit
UserGroupInformation.setConfiguration(configuration);
UserGroupInformation.loginUserFromSubject(null);
return configuration;
}
方法三:在代码里面增加hadoop的环境变量
此方法测试有效
在寻找解决方案时,突然发现,在streaming的applicationMaster中,environment中的spark properties里面只有spark的参数,缺少hadoop的参数,很奇怪,因此尝试增加hadoop参数,没想到就解决问题了。
代码如下
val builder = SparkSession.builder()
val hadoopConf = new Configuration()
// 这里的文件地址可以换成从数据库里查询
val core = new Path(“/etc/hadoop/conf/core-site.xml”)
val hdfs = new Path(“/etc/hadoop/conf/hdfs-site.xml”)
val hive = new Path(“/etc/hadoop/conf/hive-site.xml”)
val yarn = new Path(“/etc/hadoop/conf/yarn-site.xml”)
hadoopConf.addResource(core)
hadoopConf.addResource(hdfs)
hadoopConf.addResource(hive)
hadoopConf.addResource(yarn)
for (c <- hadoopConf.iterator().asScala) {
builder.config(c.getKey, c.getValue)
}
val conf = new SparkConf()
.setAppName(applicationAppName)
builder
.config(conf)
.getOrCreate()文章来源:https://www.toymoban.com/news/detail-829828.html
在用创建SparkSession的过程中,保留第二步UserGroupInformation认证的步骤,增加获取core、hdfs、hive、yarn的参数,重新提交即可,且提交命令中不需要增加–keytab /xxx/xxx/username.keytab --principal username@XXX.com命令。
方法三在本人环境总亲测成功,但是正常情况下,提交spark任务至yarn中运行,会自动将集群参数给带上去,我这里没带上去的原因未知,还在排查中。望有知道原因的大佬不吝赐教。文章来源地址https://www.toymoban.com/news/detail-829828.html
到了这里,关于spark streaming如何在kerberos认证的集群上提交任务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!