溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Kerberos環(huán)境下Java應(yīng)用程序認證超時異常是怎么回事

發(fā)布時間:2021-12-13 18:02:25 來源:億速云 閱讀:868 作者:小新 欄目:大數(shù)據(jù)

這篇文章給大家分享的是有關(guān)Kerberos環(huán)境下Java應(yīng)用程序認證超時異常是怎么回事的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

測試環(huán)境

1.CM和CDH版本為5.15.1

2.操作系統(tǒng)版本為RedHat7.2

3.集群已啟用Kerberos

問題描述

在使用JDK 8時,在Kerberos環(huán)境下應(yīng)用程序在執(zhí)行的過程中報以下錯誤:

Failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]


問題分析

在Kerberos環(huán)境下長時間運行的作業(yè)會出現(xiàn)認證失敗問題,認證失敗是由于Ticket過期導致。Ticket過期是由ticket_lifetime和renew_lifetime兩個參數(shù)控制,具體分析如下:

先了解下krb5.conf里ticket_lifetime和renew_lifetime參數(shù):

ticket_lifetime = 24h
renew_lifetime = 7d

注:這里其實還跟kdc.conf里的ticket_lifetime和renew_lifetime相關(guān),本文不做討論,假設(shè)你配置都是一致的。

每一個Kerberos的ticket,包括TGT,都有一個ticket_lifetime(默認:1天);Ticket可以被延續(xù),但最多只能延續(xù)到renew_lifetime(默認:7天),超過7天后無法再延續(xù),此時ticket失效,只能重新login。

如果你的應(yīng)用程序需要運行很長時間或者需要持續(xù)不斷地一直運行,就會有一個問題,即:

在應(yīng)用程序啟動時進行Kerberos認證登錄后,是否還需要定時renew ticket或在ticket期滿失效后使用keytab重新login?例如,是否需要在應(yīng)用程序代碼里,在每個UGI.doAS(...)前調(diào)用UGI.checkTGTAndReloginFromKeytab或者使用一個Timer周期性地調(diào)用UGI.checkTGTAndReloginFromKeytab?

關(guān)于這個問題,首先需要了解在Hadoop系統(tǒng)里是如何進行Kerberos認證的:

Hadoop Kerberos認證的主要使用場景是Hadoop RPC框架(使用SASL進行kerberos認證)。大部分Hadoop daemon進程在啟動時會調(diào)用UGI(org.apache.hadoop.security.UserGroupInformation),UGI.loginUserFromKeytab做kerberos認證并獲取ticket,并在后續(xù)每一次RPC調(diào)用時使用該ticket認證。比如,DataNode必須認證它對NameNode的RPC調(diào)用,NodeManager也必須認證它對ResourceManager的RPC調(diào)用。那么,這些daemon進程為什么能在啟動后長時間持續(xù)運行而不會出現(xiàn)kerberos ticket錯誤呢(甚至已經(jīng)超過了renew_lifetime)?這是因為Hadoop在RPC Client層實現(xiàn)了一種自動relogin機制。在Client.handleSaslConnectionFailure(org.apache.hadoop.ipc.Client)方法里有如下代碼:

      // try re-login
    if (UserGroupInformation.isLoginKeytabBased()) {
              UserGroupInformation.getLoginUser().reloginFromKeytab();
    } else if (UserGroupInformation.isLoginTicketBased()) {
        UserGroupInformation.getLoginUser().reloginFromTicketCache();
    }

Kerberos環(huán)境下Java應(yīng)用程序認證超時異常是怎么回事

上述代碼說明在使用RPC連接時,如果因為ticket失效造成認證失敗,會自動relogin。

基于以上認識,可以得出以下結(jié)論:

1.如果應(yīng)用程序的使用模式是從keytab登錄后執(zhí)行典型的Hadoop RPC Java調(diào)用(如調(diào)用HDFS FileSystem API),那么是不需要在應(yīng)用層增加renew ticket或relogin代碼的,因為RPC Client層已經(jīng)幫你實現(xiàn)了。

2.如果應(yīng)用程序的使用模式是不使用Hadoop RPC,而是調(diào)用HDFS REST API或YARN REST API(使用SPNEGO進行kerberos認證),那么需要在應(yīng)用程序里增加relogin代碼。具體實現(xiàn)方式是:

Java方式:主Java程序使用keytab調(diào)用UGI.loginUserFromKeytab登錄,然后在每個UGI.doAS前調(diào)用UGI.checkTGTAndReloginFromKeytab方法,或者另啟動一個線程周期性調(diào)用該方法。

Kerberos環(huán)境下Java應(yīng)用程序認證超時異常是怎么回事

Shell方式:主程序使用kinit登錄,然后啟動另一個子進程周期性的調(diào)用kinit -R去renew ticket或者調(diào)用kinit -kt去relogin。

需要注意的是當使用JDK 8時,UGI的relogin存在一個bug,即HADOOP-10786。該bug是因為JDK 8的Krb5LoginModule有些小改動,這些改動會造成UGI的relogin代碼認為之前的登錄并不是基于keytab登錄的。所以,UGI.reloginFromKeytab和UGI.checkTGTAndReloginFromKeytab方法實際上什么都沒有做,并沒有執(zhí)行relogin。所以,此時應(yīng)用程序仍然會報以下錯誤:

Failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]

解決辦法

對于使用JDK 8應(yīng)用程序不能正常reloginFromKeytab的 bug,workaround是:

1. 使用JDK 7而不是JDK 8,或者

2. 確保hadoop-common包含了HADOOP-10786補丁。

建議使用CDH5.13.0或者以上版本的包,這些包已經(jīng)包括了該補丁。如果仍然在IDE開發(fā)環(huán)境出現(xiàn)了以上問題,可以檢查一下IDE依賴的hadoop-common包的版本是否有問題。

感謝各位的閱讀!關(guān)于“Kerberos環(huán)境下Java應(yīng)用程序認證超時異常是怎么回事”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI