Spark 本地连接远程服务器上带有kerberos认证的Hive

Posted 董可伦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spark 本地连接远程服务器上带有kerberos认证的Hive相关的知识,希望对你有一定的参考价值。

我的原创地址:https://dongkelun.com/2021/05/19/localSparkHiveWithKerberos/

前言

因为公司的测试环境带有kerberos,而我经常需要本地连接测试集群上的hive,以进行源码调试。而本地认证远程集群的kerberos,并访问hive,和在服务器上提交Spark程序代码有些不同,所以专门研究了一下
并进行总结。

服务器上

在服务器上提交Spark程序认证kerberos比较简单,有两种方法:

  • 使用kinit 缓存票据 kinit -kt /etc/security/keytabs/hive.service.keytab hive/indata-192-168-44-128.indata.com@INDATA.COM,然后提交Spark程序即可
  • 在spark-submit 中添加参数 --principal hive/indata-192-168-44-128.indata.com@INDATA.COM --keytab /etc/security/keytabs/hive.service.keytab

本地

本地连接,稍微复杂点,首先要配好环境,比如Hadoop的环境变量、winutils等,然后需要配置hosts,将服务器上的/etc/hosts里面的内容拷贝出来,粘贴Windows上的hosts文件里即可

代码

首先需要将集群上的hive-site.xml,core-site.xml,yarn-site.xml,hdfs-site.xml拷贝到src/main/resources文件夹中,其中hive-site.xml是为了连接hive,core-site.xml、hdfs-site.xml和yarn-site.xml是为了认证kerberos

package com.dkl.blog.spark.hive

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.security.UserGroupInformation
import org.apache.spark.sql.SparkSession

/**
 * Created by dongkelun on 2021/5/18 19:29
 *
 * Spark 本地连接远程服务器上带有kerberos认证的Hive
 */
object LocalSparkHiveWithKerberos 

  def main(args: Array[String]): Unit = 

    try 

      //等同于把krb5.conf放在$JAVA_HOME\\jre\\lib\\security,一般写代码即可
      System.setProperty("java.security.krb5.conf", "D:\\\\conf\\\\inspur\\\\krb5.conf")

      //下面的conf可以注释掉是因为在core-site.xml里有相关的配置,如果没有相关的配置,则下面的代码是必须的
      //      val conf = new Configuration
      //      conf.set("hadoop.security.authentication", "kerberos")
      //      UserGroupInformation.setConfiguration(conf)
      UserGroupInformation.loginUserFromKeytab("hive/indata-192-168-44-128.indata.com@INDATA.COM", "D:\\\\conf\\\\inspur\\\\hive.service.keytab")
      println(UserGroupInformation.getCurrentUser, UserGroupInformation.getLoginUser)


     catch 
      case e: Exception =>
        e.printStackTrace()
    

    val spark = SparkSession.builder()
      .master("local[*]")
      .appName("LocalSparkHiveWithKerberos")
      //      .config("spark.kerberos.keytab", "hive/indata-192-168-44-128.indata.com@INDATA.COM")
      //      .config("spark.kerberos.principal", "D:\\\\conf\\\\inspur\\\\hive.service.keytab")
      .enableHiveSupport()
      .getOrCreate()

    spark.table("sjtt.trafficbase_cljbxx").show()

    spark.stop()
  


代码已提交到github

运行结果

异常解决

异常信息

org.apache.hadoop.security.AccessControlException: SIMPLE authentication is not enabled.  Available:[TOKEN, KERBEROS]

异常解决过程

异常再现是将core-site.xml删除,然后将代码中注释的conf打开。
这样从打印的UserGroupInformation.getCurrentUser信息可以发现kerberos认证是成功的,而且代码中设置了hadoop.security.authentication为kerberos,但是依旧报authentication为SIMPLE的异常,网上查资料查了很久都没解决,只能自己进行研究,在本地的Spark UI 界面的environment中查看Spark的环境配置信息发现,虽然在Spark的代码中配置了.config(“spark.kerberos.keytab”, “hive/indata-192-168-44-128.indata.com@INDATA.COM”)、.config(“spark.kerberos.principal”, “D:\\conf\\inspur\\hive.service.keytab”),且在ui界面中也显示相同的配置,如下图

但是依旧报同样的异常信息,后来在界面上发现,除了Spark Properties还有Hadoop Properties,代码中的配置只是改变了Spark Properties,没有改变Hadoop Properties,而Hadoop Properties中的hadoop.security.authentication依旧为simple,这有可能是导致异常的原因。


那么如何改变Hadoop Properties,在Spark源码搜索发现如下文档

# Custom Hadoop/Hive Configuration

If your Spark application is interacting with Hadoop, Hive, or both, there are probably Hadoop/Hive
configuration files in Spark's classpath.

Multiple running applications might require different Hadoop/Hive client side configurations.
You can copy and modify `hdfs-site.xml`, `core-site.xml`, `yarn-site.xml`, `hive-site.xml` in
Spark's classpath for each application. In a Spark cluster running on YARN, these configuration
files are set cluster-wide, and cannot safely be changed by the application.

The better choice is to use spark hadoop properties in the form of `spark.hadoop.*`, and use
spark hive properties in the form of `spark.hive.*`.
For example, adding configuration "spark.hadoop.abc.def=xyz" represents adding hadoop property "abc.def=xyz",
and adding configuration "spark.hive.abc=xyz" represents adding hive property "hive.abc=xyz".
They can be considered as same as normal spark properties which can be set in `$SPARK_HOME/conf/spark-defaults.conf`

文档说最好的选择是在代码中设置Spark.hadoop.*,即.config(“Spark.hadoop.security.authentication”, “kerberos”),然后尝试了一下,发现这样仅仅是改变的Spark Properties,依旧是同样的异常,也可能是我理解的有问题。

异常解决方案

最后的解决方案是按文档上的将core-site.xml和hdfs-site.xml拷贝到Spark的classpath下,即上面提到的src/main/resources,但是这样依旧可能没效果,原因是,配置文件没有同步到target/classes,这里需要在idea里点Build-Rebuild Project,然后确认一下target/classes是否有了core-site.xml文件就可以了

相关阅读

以上是关于Spark 本地连接远程服务器上带有kerberos认证的Hive的主要内容,如果未能解决你的问题,请参考以下文章

spark 2.x在windows环境使用idea本地调试启动了kerberos认证的hive

使用 Kerberos 设置 Spark SQL 连接

本地Spark连接远程集群Hive(Scala/Python)

CDH开启kerberos后在第三方机器上部署Spark程序问题解决

远程 SQL Server 连接问题

将 sparklyr 连接到远程 spark 连接