我們最近在我們的 Spark 集群上啟用了 Kerberos 身份驗證,但是我們發現當我們在集群模式下提交 Spark 作業時,代碼無法連接到 Hive。我們是否應該使用 Kerberos 對 Hive 進行身份驗證,如果是,如何?如下詳述,我認為我們必須指定 keytab 和 principal,但我不知道具體是什么。
這是我們得到的例外:
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
這是產生例外的腳本,如您所見,發生在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-submit cli 一起使用,它也有望與 Livy 一起使用。我們使用的是 Spark 3.1.1 和 Kerberos 1.10.3-30。
只有當我們使用spark-submit --deploy-mode cluster時才會出現例外,使用客戶端模式時沒有例外并且創建了資料庫。
當我們洗掉例外時.enableHiveSupport,例外也消失了,因此它顯然與對 Hive 的身份驗證有關。不過,我們確實需要 Hive 倉庫,因為我們需要從多個 Spark 會話中訪問表,因此它們需要被持久化。
我們可以訪問 HDFS,也可以在集群模式下sc.textFile('/example/data/fruits.txt').collect()正常作業。
類似的問題和可能的解決方案
在例外中,我看到它是試圖訪問頭節點的作業節點。埠是 8020,我認為是 namenode 埠,所以這聽起來確實與 HDFS 有關 - 除了據我了解我們可以訪問 HDFS,但不能訪問 Hive。
- https://spark.apache.org/docs/latest/running-on-yarn.html#kerberos它建議明確指定 principal 和 keytab 檔案,所以我找到了 keytab 檔案
klist -k并添加到 spark-submit 命令列--principal myusername@MYREALM --keytab /etc/krb5.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 檔案,因為當我klist -k /etc/krb5.keytab使用檔案時,我只會得到帶有HN0-PT-DEV@MYREALM 和host/hn0-pt-dev.myrealm@MYREALM. 如果我在其中查看 hdfs/hive 的密鑰表,/etc/security/keytabs我也只會看到 hdfs/hive 用戶的條目。
當我嘗試添加如何使用 Apache Spark 使用 Kerberos 查詢 Hive 表中指定的所有 extraJavaOptions 時?但不要指定主體/密鑰表,KrbException: Cannot locate default realm即使默認領域/etc/krb5.conf是正確的,我也會得到。
在 Ambari 中,我可以看到設定spark.yarn.keytab={{hive_kerberos_keytab}}和spark.yarn.principal={{hive_kerberos_principal}}.
- https://docs.microsoft.com/en-us/azure/hdinsight/hdinsight-faq#how-do-i-create-a-keytab-for-an-hdinsight-esp-cluster-我為我的用戶并指定該檔案,但這沒有幫助。
似乎許多其他答案/網站也建議明確指定主體/密鑰表:
- Spark on YARN Secured hbase用于 HBase 而不是 Hive,但結論相同。
- 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 的問題
- spark-submit 由于 Kerberos 無法連接到 Metastore:由 GSSException 引起:未提供有效憑據。但在本地客戶端模式下作業
- https://docs.cloudera.com/documentation/enterprise/5-7-x/topics/sg_spark_auth.html#concept_bvc_pcy_dt(我找不到來自微軟的類似檔案)
- spark-submit,客戶端無法通過:[TOKEN,KERBEROS] 進行身份驗證;
其他問題:
- 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 [在啟動時] 的令牌”是什么意思。我確實重新啟動了集群上的所有服務,但這并沒有幫助。
- 在 Kubernetes 集群上運行的 Spark 獨立集群中的 Hadoop 集群的 Kerberos 身份驗證這是具有兩個集群的情況。如此處所述:
在 yarn-cluster 模式下,Spark 客戶端使用本地 Kerberos 票證連接到 Hadoop 服務并檢索特殊的身份驗證令牌,然后將其傳送到運行驅動程式的 YARN 容器;然后驅動程式將令牌廣播給執行程式
- 在 Kubernetes 上運行 Spark 以訪問 kerberized Hadoop 集群時,如何解決執行程式上的“未啟用簡單身份驗證”錯誤?對于較舊的 Spark 版本。
- 無法使用安全的 kerberos 連接到 HIVE。我正在使用 UserGroupInformation.loginUserFromKeytab()關于 JAAS
- 紗線節點管理器上的 Spark-submit 作業失敗,并出現錯誤客戶端無法通過以下方式進行身份驗證:[TOKEN,KERBEROS]無答案
- 客戶端無法通過以下方式進行身份驗證:[TOKEN,KERBEROS)對我來說沒有意義。
- 在 Kerberos 環境中無法通過 Spark 訪問 Hive:客戶端無法通過以下方式進行身份驗證:[TOKEN, KERBEROS]添加 spark.security.credentials.hadoopfs.enabled=true
- https://funclojure.tumblr.com/post/155129283948/hdfs-kerberos-java-client-api-關于罐子的痛苦
- org.apache.hadoop.security.AccessControlException:客戶端無法通過以下方式進行身份驗證:[TOKEN,KERBEROS] 問題無答案
- https://issues.apache.org/jira/browse/SPARK-27554沒有答案
- java.io.IOException:org.apache.hadoop.security.AccessControlException:客戶端無法通過身份驗證:[TOKEN,KERBEROS] old
可能要嘗試的事情:
- https://spark.apache.org/docs/2.1.1/running-on-yarn.html#troubleshooting-kerberos啟用更詳細的日志記錄。
- https://docs.microsoft.com/en-us/azure/hdinsight/hdinsight-linux-ambari-ssh-tunnel查看 Namenode UI 可能會提供一些資訊
更新
以 Hive 用戶身份登錄時:
kinit然后提供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
uj5u.com熱心網友回復:
通常,您必須完成 [kinit successfully]/[pass a principle/keytab] 才能將 Kerberos 與 spark/hive 一起使用。它們是一些使 hive 使用復雜化的設定。(模仿)
一般來說,如果您可以 kinit 并使用 hdfs 寫入您自己的檔案夾,那么您的 keytab 正在作業:
kinit #enter user info
hdfs dfs -touch /home/myuser/somefile #gurantees you have a home directory... spark needs this
一旦你知道這是有效的,你應該檢查你是否可以寫信給 hive:
要么使用 JDBC 連接,要么使用帶有連接字串的直線,如下所示
jdbc:hive2://HiveHost:10001/default;[email protected];
這有助于找出問題所在。
如果您正在查看配置單元的問題,您需要檢查模擬:
HiveServer2 模擬 重要提示:這不是實作 HiveServer2 授權的推薦方法。Cloudera 建議您改用 Sentry 來實作這一點。HiveServer2 模擬允許用戶以連接用戶而不是超級用戶身份執行查詢和訪問 HDFS 檔案。使用 ACL(訪問控制串列)中指定的 HDFS 權限在檔案級別應用訪問策略。啟用 HiveServer2 模擬會繞過端到端授權程序中的 Sentry。具體來說,盡管 Sentry 對 Hive 倉庫中的表和視圖實施訪問控制策略,但它不控制對表下的 HDFS 檔案的訪問。
如果您在 Windows 上,則應注意票證快取。您應該考慮設定自己的個人票證快取位置,因為 Windows 通常為所有用戶使用一個通用位置。(這允許用戶在彼此之上登錄,從而產生奇怪的錯誤。)
如果您遇到 Hive 問題,Hive 日志本身通常可以幫助您了解該程序為何不起作用。(但只有在某些 kerberos 成功時,您才會有日志,如果完全不成功,您將什么也看不到。)
檢查 Ranger 并查看是否有任何錯誤。
- 如果要使用集群模式訪問Hive倉庫,需要指定keytab和principal才能spark-submit(這個在官方檔案里很清楚)
使用Keytab 通過為Spark 提供一個principal 和keytab(例如使用帶有--principal 和--keytab 引數的spark-submit),應用程式將保持一個有效的Kerberos 登錄,該登錄可用于無限期地檢索委托令牌。
請注意,在集群模式下使用 keytab 時,它將被復制到運行 Spark 驅動程式的機器上。對于 YARN,這意味著使用 HDFS 作為 keytab 的暫存區域,因此強烈建議至少對 YARN 和 HDFS 進行加密保護。
- 您需要創建自己的密鑰表
如果您使用 Livy,--proxy-user 將與--principal 沖突,但這很容易解決。(使用:livy.impersonation.enabled=false)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/465527.html
