Hadoop權限認證的執行流程


Hadoop分布式文件系統實現了一個和POSIX系統類似的文件和目錄的權限模型。每個文件和目錄有一個所有者(owner)和一個組(group)。文件或目錄對其所有者、同組的其他用戶以及所有其他用戶分別有着不同的權限。對文件而言,當讀取這個文件時需要有r權限,當寫入或者追加到文件時需要有w權限。對目錄而言,當列出目錄內容時需要具有r權限,當新建或刪除子文件或子目錄時需要有w權限,當訪問目錄的子節點時需要有x權限。每個訪問HDFS的用戶進程的標識分為兩個部分,分別是用戶名和組名列表。每次用戶進程訪問一個文件或目錄foo,HDFS都要對其進行權限檢查:
  1、如果用戶即foo的所有者,則檢查所有者的訪問權限;
  2、如果foo關聯的組在組名列表中出現,則檢查組用戶的訪問權限;
  3、否則檢查foo其他用戶的訪問權限。

如果權限檢查失敗,則客戶的操作會失敗。所以如果我們以某個用戶ls HDFS上某個文件夾時可能會出現以下的錯誤信息:

    Caused by: org.apache.hadoop.ipc.RemoteException  
    (org.apache.hadoop.security.AccessControlException):   
    Permission denied: user=iteblog, access=EXECUTE,  
     inode="/user/hadoop":iteblog:iteblog:drwx------  

上面的iteblog用戶試圖訪問HDFS上/user/hadoop目錄下的文件,但是iteblog是屬於iteblog組的,而/user/hadoop目錄的權限是drwx------,也就是只有該文件夾所有者才能訪問這個目錄。仔細研究,我們可以找到這個用戶獲取模塊是在UserGroupInformation類中獲取的,部分代碼如下:

    Principal user = null;  
    // if we are using kerberos, try it out  
    if (isAuthenticationMethodEnabled(AuthenticationMethod.KERBEROS)) {  
      user = getCanonicalUser(KerberosPrincipal.class);  
      if (LOG.isDebugEnabled()) {  
        LOG.debug("using kerberos user:"+user);  
      }  
    }  
    //If we don't have a kerberos user and security is disabled, check  
    //if user is specified in the environment or properties  
    if (!isSecurityEnabled() && (user == null)) {  
      String envUser = System.getenv(HADOOP_USER_NAME);  
      if (envUser == null) {  
        envUser = System.getProperty(HADOOP_USER_NAME);  
      }  
      user = envUser == null ? null : new User(envUser);  
    }  
    // use the OS user  
    if (user == null) {  
      user = getCanonicalUser(OS_PRINCIPAL_CLASS);  
      if (LOG.isDebugEnabled()) {  
        LOG.debug("using local user:"+user);  
      }  
    }  
    // if we found the user, add our principal  
    if (user != null) {  
      subject.getPrincipals().add(new User(user.getName()));  
      return true;  
    }  
    LOG.error("Can't find user in " + subject);  
    throw new LoginException("Can't find user name");  

從上面代碼片段可以知道,Hadoop先判斷集群是否啟用了Kerberos授權,如果是,則直接從配置中獲取用戶(可以為空);如果不是,則往下走。然后判斷是否啟用了安全認證,安全認證是通過下面參數配置的:

    <property>  
      <name>hadoop.security.authentication</name>  
      <value>simple</value>  
    </property>  

默認是不啟用的。所以如果沒有啟用安全認證或者從Kerberos獲取的用戶為null,那么獲取HADOOP_USER_NAME環境變量,並將它的值作為Hadoop執行用戶。如果我們沒有設置HADOOP_USER_NAME環境變量,那么程序將調用whoami來獲取當前用戶,並用groups來獲取用戶所在組。

  根據上面的分析,我們有兩個辦法來解決用戶訪問HDFS失敗的問題(這兩個方法能夠使用的前提都是沒有啟用安全認證):

1、我們可以在啟動程序之前設置HADOOP_USER_NAME環境變量,比如:

[blog@node1 ~]$ export HADOOP_USER_NAME=node1  

2、我們可以自定義whoami和groups命令,返回咱們需要的用戶或者組。

只要Hadoop沒有啟用安全認證,我們想咋修改用戶和用戶所在組就咋修改,這樣對存在HDFS上的文件來說是非常不利的。


免責聲明!

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



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