從 "org.apache.hadoop.security.AccessControlException:Permission denied: user=..." 看Hadoop 的用戶登陸認證


假設遠程提交任務給Hadoop 可能會遇到 "org.apache.hadoop.security.AccessControlException:Permission denied: user=..." , 當然,假設是spark over YARN, 也相同會遇到相似的問題,比如:

 An error occurred while calling None.org.apache.spark.api.java.JavaSparkContext.
: org.apache.hadoop.security.AccessControlException: Permission denied: user=abel, access=WRITE, inode="/user/abel/.sparkStaging/application_1460633311001_0032":hdfs:hdfs:drwxr-xr-x

hadoop 的用戶鑒權是基於JAAS的。當中hadoop.security.authentication屬性 有simple 和kerberos 等方式。假設hadoop.security.authentication等於”kerberos”,那么是“hadoop-user-kerberos”或者“hadoop-keytab-kerberos”。否則是“hadoop-simple”。 當用戶登陸的時候。若org.apache.hadoop.security.User為空,那么說明尚未登錄過,調用靜態方法getLoginUser()創建org.apache.hadoop.security.UserGroupInformatio實例,在getLoginUser()中又會調用HadoopLoginModule的login()和commit()方法。


在使用了kerberos的情況下。從javax.security.auth.kerberos.KerberosPrincipal的實例獲取username。在沒有使用kerberos時。首先讀取hadoop 的系統環境變量。假設沒有的話。對於windows 從com.sun.security.auth.NTUserPrincipal 獲取username。對於類unix 從com.sun.security.auth.UnixPrincipal 中獲得username,然后再看該用戶屬於哪個group,從而完畢登陸認證。


基本理解了問題的根源,那么這個“org.apache.hadoop.security.AccessControlException:Permission denied: user=...”異常信息是怎么產生的呢?遠程提交,假設沒有hadoop 的系統環境變量。就會讀取當前主機的username,結果Hadoop集群中沒有該用戶。所以杯具了。


至於問題的解決,以mac 為例。 將

export HADOOP_USER_NAME = hdfs 

加入到 ~/.bash_profile 中。

 $ source  ~/.bash_profile 


接下來。繼續提交任務到 hadoop 集群,everything is OK。 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM