我们最近在 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}
。
看来很多其他答案/网站也建议明确指定principal/keytab:
其他问题:
为了让Spark应用程序与HDFS、HBase和Hive进行交互,它必须使用启动应用程序的用户的Kerberos凭证来获取相关的令牌——也就是说,其身份将成为启动的Spark应用程序的身份的主体。这通常在启动时完成:在安全集群中,Spark将自动获取集群的HDFS文件系统的令牌,可能还会获取HBase和Hive的令牌。
嗯,启动应用程序的用户拥有有效的票据,可以在klist
的输出中看到。用户具有blob存储的参与者访问权限(不确定是否确实需要)。不过,我不明白“Spark将[在发布时]自动获得Hive的令牌”是什么意思。我确实重新启动了集群上的所有服务,但这无济于事。
在yarn-cluster模式下,Spark客户端使用本地Kerberos票据连接到Hadoop服务并检索特殊的auth令牌,然后将这些令牌发送到运行驱动程序的yarn容器;然后,驱动程序将令牌广播给执行器
可能尝试的事情:
作为配置单元用户登录时:
< 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
一般来说,你必须完成一个[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,看看是否有错误。
使用Keytab通过向Spark提供主体和keytab(例如,使用带有--主体和--keytab参数的Spark提交),应用程序将维护一个有效的Kerberos登录名,该登录名可用于无限期检索委托令牌。
请注意,在群集模式下使用密钥表时,该密钥表将被复制到运行 Spark 驱动程序的计算机。对于 YARN,这意味着使用 HDFS 作为密钥表的暂存区域,因此强烈建议至少使用加密来保护 YARN 和 HDFS。
无法从用户处获取密码
如果你使用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
我正在使用一个keytab,并使用windows命令行上的kinit命令设置它。我得到消息“new ticket is storage in cache file”。之后,当我运行java应用程序访问keytab文件以获取密钥时,我得到以下错误。 C:\users\cxxxxx\git\abcd.keytab refreshKrb5Config为false主体为xxxx_dev@xxxx.xxxx
我有公钥和私钥(PKCS#1:即具有“BEGIN RSA PRIVATE KEY”)作为单独的字符串输入。这些密钥是使用以下命令创建的: 客户端的内容。csr是作为公钥字符串提供的,客户端的内容是私有的。密钥作为私钥字符串提供 现在我必须创建java密钥库,添加这些密钥并务实地导出为JKS文件。我经历了多个链接并尝试了弹跳城堡示例,但我得到了以下错误。 我正在编写一个kafka客户端,启用了SSL
问题内容: 我需要导入证书,以便向Spring Boot应用程序中的外部服务发出http请求。 我该如何设置Spring Boot来做到这一点? 那里有很多信息,但我发现所有这些都令人困惑。似乎我可能只需要创建类似“ truststore.jks”密钥库的内容并导入正确的证书,然后将一些条目添加到我的application.properties中即可。 问题答案: 打开您的终端或 回答所有问题。在
如何用Apache CXF实现这一点?