当前位置: 首页 > 知识库问答 >
问题:

AccessControlException:使用Hive仓库时,客户端无法通过[TOKEN,KERBEROS]进行身份验证

贡俊
2023-03-14

我们最近在 Spark 群集上启用了 Kerberos 身份验证,但我们发现,当我们在群集模式下提交 Spark 作业时,代码无法连接到 Hive。我们是否应该使用 Kerberos 对 Hive 进行身份验证,如果是,如何进行身份验证?如下所述,我认为我们必须指定keytab和校长,但我不知道具体是什么。

这是我们得到的例外:

Traceback (most recent call last):
  File "/mnt/resource/hadoop/yarn/local/usercache/sa-etl/appcache/application_1649255698304_0003/container_e01_1649255698304_0003_01_000001/__pyfiles__/utils.py", line 222, in use_db
    spark.sql("CREATE DATABASE IF NOT EXISTS `{db}`".format(db=db))
  File "/usr/hdp/current/spark3-client/python/pyspark/sql/session.py", line 723, in sql
    return DataFrame(self._jsparkSession.sql(sqlQuery), self._wrapped)
  File "/usr/hdp/current/spark3-client/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py", line 1305, in __call__
  File "/usr/hdp/current/spark3-client/python/pyspark/sql/utils.py", line 117, in deco
    raise converted from None
pyspark.sql.utils.AnalysisException: java.lang.RuntimeException: java.io.IOException: DestHost:destPort hn1-pt-dev.MYREALM:8020 , LocalHost:localPort wn1-pt-dev/10.208.3.12:0. Failed on local exception: java.io.IOException: org.apache.hadoop.security.AccessControlException: Client cannot authenticate via:[TOKEN, KERBEROS]

此外,我看到了这个异常:

org.apache.hadoop.security.AccessControlException: Client cannot authenticate via:[TOKEN, KERBEROS], while invoking ClientNamenodeProtocolTranslatorPB.getFileInfo over hn0-pt-dev.myrealm/10.208.3.15:8020

这是产生异常的脚本,如您所见,它发生在< code>CREATE DATABASE上:

from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('Test').enableHiveSupport().getOrCreate()
spark.sql("CREATE DATABASE IF NOT EXISTS TestDb")

我们在 Azure 中有一个启用了 ESP 的 HDInsight 群集,它位于虚拟网络中。AADDS 可以很好地登录到群集。群集连接到存储帐户,与 ABFS 通信,并将 Hive 仓库存储在该帐户上。我们正在使用纱线。我们希望使用 Azure 数据工厂中的 PySpark 执行 Spark 作业,该工厂使用 Livy,但如果我们可以让它与 spark 提交 cli 一起使用,则希望它也可以与 Livy 配合使用。我们使用的是 Spark 3.1.1 和 Kerberos 1.10.3-30。

仅当我们使用 spark-submit --deploy 模式群集时才会发生异常,使用客户端模式时没有异常,并且创建了数据库

当我们删除 .enableHiveSupport 时,异常也会消失,因此它显然与对 Hive 的身份验证有关。不过,我们确实需要 Hive 仓库,因为我们需要从多个 Spark 会话中访问表,以便需要持久保存它们。

我们可以访问HDFS,也可以在集群模式下,因为sc.textFile('/example/data/fruits.txt')。

在例外中,我看到是工作线程节点尝试访问头节点。端口是8020,我认为是名称节点端口,所以这听起来确实与HDFS有关 - 除了据我所知,我们可以访问HDFS,但不能访问Hive。

  • https://spark.apache.org/docs/latest/running-on-yarn.html#kerberos它建议显式指定主体和keytab文件,所以我找到了带有klist-k的keytab文件,并将其添加到spack-提交命令行--主体myusername@MYREALM--keytab /etc/krb5.keytab,这与下面链接的问题之一中的keytab文件相同,但是我得到了
Exception in thread "main" org.apache.hadoop.security.KerberosAuthException: failure to login: for principal: myusername@MYREALM from keytab /etc/krb5.keytab javax.security.auth.login.LoginException: Unable to obtain password from user

不过,可能我有错误的keytab文件,因为当我< code > klist-k/etc/krb5 . keytab 该文件时,我只得到带有类似< code>HN0-PT-DEV@MYREALM 和< code > host/HN0-PT-DEV . my realm @ my realm 的条目的槽。如果我在< code >/etc/security/keytabs 中查找hdfs/hive的key tabs,我也只能看到hdfs/hive用户的条目。

当我尝试添加在如何使用Apache Spark查询Hive表与Kerberos?,但不指定主体/keytab中指定的所有额外的JavaOptions,我得到KrbException:无法找到默认领域,即使/etc/krb5.conf中的默认领域是正确的。

在Ambari中,我可以看到设置spark.yarn。keytab={{hivekerberoskeytab}}spark.yarn.principal={{hivekerkerberos_principal}

  • https://learn.microsoft.com/en-us/azure/hdinsight/hdinsight-faq#how-do-i-create-a-keytab-for-an-hdinsight-esp-cluster-我为我的用户创建了一个keytab,并指定了该文件,但这没有帮助

看来很多其他答案/网站也建议明确指定principal/keytab:

  • 火花在纱线上安全hbase用于HBase而不是蜂巢,但结论相同。
  • https://www.ibm.com/docs/en/spectrum-conductor/2.4.1?topic=ssbaig-submitting-spark-batch-applications-kerberos-enabled-hdfs-keytab
  • 与 Spark Java API、Kerberos 和 Hive 有关的问题
  • 由于 Kerberos 导致 spark 提交无法连接到元存储: 由 GSSException 引起:未提供有效的凭据,但在本地客户端模式下工作
  • https://docs.cloudera.com/documentation/enterprise/5-7-x/topics/sg_spark_auth.html#concept_bvc_pcy_dt(我无法从微软找到类似的文档)
  • 火花提交,客户端无法通过以下方式进行身份验证:[令牌,KERBEROS];

其他问题:

    < Li > https://spark . Apache . org/docs/2 . 1 . 1/running-on-yarn . html # running-in-a-secure-cluster从官方文档开始:它解释说

为了让Spark应用程序与HDFS、HBase和Hive进行交互,它必须使用启动应用程序的用户的Kerberos凭证来获取相关的令牌——也就是说,其身份将成为启动的Spark应用程序的身份的主体。这通常在启动时完成:在安全集群中,Spark将自动获取集群的HDFS文件系统的令牌,可能还会获取HBase和Hive的令牌。

嗯,启动应用程序的用户拥有有效的票据,可以在klist的输出中看到。用户具有blob存储的参与者访问权限(不确定是否确实需要)。不过,我不明白“Spark将[在发布时]自动获得Hive的令牌”是什么意思。我确实重新启动了集群上的所有服务,但这无济于事。

  • 在库伯内特斯集群上运行的Spark独立集群与Hadoop集群进行Kerberos身份验证。这是两种集群的情况。如下所述:

在yarn-cluster模式下,Spark客户端使用本地Kerberos票据连接到Hadoop服务并检索特殊的auth令牌,然后将这些令牌发送到运行驱动程序的yarn容器;然后,驱动程序将令牌广播给执行器

    < li >在Kubernetes上运行Spark访问Kerberos化的Hadoop集群时,如何解决执行器上出现的“未启用简单身份验证”错误?对于较旧的Spark版本。 < li >无法使用安全的kerberos连接到配置单元。我正在使用user group information . loginuserfromkeytab()关于JAAS的一些信息 < li >纱线节点管理器上的Spark-submit作业失败,错误为客户端无法通过[TOKEN,KERBEROS]进行身份验证无应答 < li >客户端无法通过[TOKEN,KERBEROS进行身份验证,这对我没有意义。 < li >无法通过Kerberos环境中的Spark访问配置单元:客户端无法通过[TOKEN,KERBEROS]添加Spark . security . credentials . Hadoop fs . enabled = true进行身份验证 < Li > https://func lojure . Tumblr . com/post/155129283948/HDFS-Kerberos-Java-client-API-关于jar的烦恼 < Li > org . Apache . Hadoop . security . accesscontrolexception:客户端无法通过以下方式进行身份验证:[TOKEN,KERBEROS] Issue No answer < Li > https://issues . Apache . org/jira/browse/SPARK-27554无应答 < Li > Java . io . io exception:org . Apache . Hadoop . security . accesscontrolexception:客户端无法通过:[TOKEN,KERBEROS] old进行身份验证

可能尝试的事情:

  • https://spark.apache.org/docs/2.1.1/running-on-yarn.html#troubleshooting-kerberos启用更详细的日志记录。
  • https://learn.microsoft.com/en-us/azure/hdinsight/hdinsight-linux-ambari-ssh-tunnel查看Namenode UI可能会提供一些信息

作为配置单元用户登录时:

< code>kinit然后提供< code>hive密码:

Password for hive/hn0-pt-dev.myrealm@MYREALM: 
kinit: Password incorrect while getting initial credentials


hive@hn0-pt-dev:/tmp$ klist -k /etc/security/keytabs/hive.service.keytab
Keytab name: FILE:/etc/security/keytabs/hive.service.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   0 hive/hn0-pt-dev.myrealm@MYREALM
   0 hive/hn0-pt-dev.myrealm@MYREALM
   0 hive/hn0-pt-dev.myrealm@MYREALM
   0 hive/hn0-pt-dev.myrealm@MYREALM
   0 hive/hn0-pt-dev.myrealm@MYREALM
hive@hn0-pt-dev:/tmp$ kinit -k /etc/security/keytabs/hive.service.keytab
kinit: Client '/etc/security/keytabs/hive.service.keytab@MYREALM' not found in Kerberos database while getting initial credentials

共有1个答案

陈文景
2023-03-14

一般来说,你必须完成一个[kinit成功]/[通过一个原则/关键选项卡]才能使用带有火花/蜂巢的Kerberos。他们的一些设置使蜂巢的使用变得复杂。(模拟)

一般来说,如果您可以kinit并使用hdfs写入您自己的文件夹,那么您的keytab就可以工作:

kinit #enter user info
hdfs dfs -touch /home/myuser/somefile #gurantees you have a home directory... spark needs this

一旦你知道这是有效的,你应该检查你是否可以写到蜂巢:

要么使用JDBC连接,要么使用带有如下连接字符串的直线

jdbc:hive2://HiveHost:10001/default;principal=myuser@HOST1.COM;

这有助于发现问题所在。

如果您正在查看配置单元的问题,则需要检查模拟:

蜂巢服务器 2 模拟 重要提示:这不是实现蜂巢服务器 2 授权的推荐方法。云端建议您使用哨兵来实现这一点。HiveServer2 模拟允许用户以连接用户(而不是超级用户)的身份执行查询和访问 HDFS 文件。访问策略使用 ACL(访问控制列表)中指定的 HDFS 权限在文件级别应用。启用 HiveServer2 模拟会从端到端授权过程中绕过 Sentry。具体来说,尽管 Sentry 对 Hive 仓库中的表和视图强制实施访问控制策略,但它不控制对表基础的 HDFS 文件的访问。这意味着,对仓库中的表没有 Sentry 权限的用户仍然可以绕过 Sentry 授权检查,并对仓库中的表执行作业和查询,只要他们对支持该表的 HDFS 文件具有权限即可。

如果您在窗口中,则应注意票证缓存。您应考虑设置自己的个人票证缓存位置,因为通常 Windows 对所有用户使用一个通用位置。(这允许用户相互登录,从而产生奇怪的错误。

如果您遇到hive问题,hive日志本身通常会帮助您理解为什么这个过程不起作用。(但是只有当一些kerberos成功时,您才会有日志,如果它完全不成功,您将看不到任何东西。)

检查Ranger,看看是否有错误。

  • 如果您想使用集群模式并访问Hive仓库,则需要指定keytab和principal来触发提交(这在官方文档中很清楚)

使用Keytab通过向Spark提供主体和keytab(例如,使用带有--主体和--keytab参数的Spark提交),应用程序将维护一个有效的Kerberos登录名,该登录名可用于无限期检索委托令牌。

请注意,在群集模式下使用密钥表时,该密钥表将被复制到运行 Spark 驱动程序的计算机。对于 YARN,这意味着使用 HDFS 作为密钥表的暂存区域,因此强烈建议至少使用加密来保护 YARN 和 HDFS

  • 您需要创建自己的keytab键
  • 创建keytab后,请确保正确的用户拥有它的权限,否则您将再次获得无法从用户处获取密码

如果你使用Livy - proxy-user会和- principal冲突,但是这很容易解决。(use:livy . impersonation . enabled = false)

 类似资料:
  • 我正在对经过kerberos身份验证的REST服务执行https请求。如果我用的是键盘,一切都很好。但是,我有一个要求,我应该使用kerberos票证缓存文件,该文件是在使用其密码登录工作站时创建的。 我会用我的域名替换域名。组件对象模型 因此,klist显示: 像这样使用curl工作正常: 现在,让我们回到代码。我的登录。conf是这样的: 我的超文本传输协议客户端的相关java代码是: 在此之

  • 我有一个.NETWCF客户端与Java服务器组件进行对话。服务器端身份验证通过配置为反向代理的中间Apache服务器完成。 NET客户端的配置如下: Apache配置为需要Kerveros身份验证: 如果我在Windows 7上启动我的应用程序,一切都按预期工作:. NET客户端使用Kerberos,Apache验证客户端,我可以使用Spring Security性访问客户端凭据。 如果我在Win

  • 我有公钥和私钥(PKCS#1:即具有“BEGIN RSA PRIVATE KEY”)作为单独的字符串输入。这些密钥是使用以下命令创建的: 客户端的内容。csr是作为公钥字符串提供的,客户端的内容是私有的。密钥作为私钥字符串提供 现在我必须创建java密钥库,添加这些密钥并务实地导出为JKS文件。我经历了多个链接并尝试了弹跳城堡示例,但我得到了以下错误。 我正在编写一个kafka客户端,启用了SSL

  • 我正在使用一个keytab,并使用windows命令行上的kinit命令设置它。我得到消息“new ticket is storage in cache file”。之后,当我运行java应用程序访问keytab文件以获取密钥时,我得到以下错误。 C:\users\cxxxxx\git\abcd.keytab refreshKrb5Config为false主体为xxxx_dev@xxxx.xxxx

  • 问题内容: 我需要导入证书,以便向Spring Boot应用程序中的外部服务发出http请求。 我该如何设置Spring Boot来做到这一点? 那里有很多信息,但我发现所有这些都令人困惑。似乎我可能只需要创建类似“ truststore.jks”密钥库的内容并导入正确的证书,然后将一些条目添加到我的application.properties中即可。 问题答案: 打开您的终端或 回答所有问题。在

  • 如何用Apache CXF实现这一点?