1. 程式人生 > >Hadoop2.6新增使用者隔離

Hadoop2.6新增使用者隔離

1.hadoop檔案許可權介紹

  (這部分內容參考成品  https://blog.csdn.net/skywalker_only/article/details/40709447)

之前在論壇看到一個關於HDFS許可權的問題,當時無法回答該問題。無法回答並不意味著對HDFS許可權一無所知,而是不能準確完整的闡述HDFS許可權,因此決定系統地學習HDFS檔案許可權。HDFS的檔案和目錄許可權模型共享了POSIX(Portable Operating System Interface,可移植作業系統介面)模型的很多部分,比如每個檔案和目錄與一個擁有者和組相關聯,檔案或者目錄對於擁有者、組內的其它使用者和組外的其它使用者有不同的許可權等。與POSIX模型不同的是,HDFS中的檔案沒有可執行檔案的概念,因而也沒有setuid和setgid,雖然目錄依然保留著可執行目錄的概念(x),但對於目錄也沒有setuid和setgid。貼上位(sticky bit)可以用在目錄上,用於阻止除超級使用者,目錄或檔案的擁有者外的任何刪除或移動目錄中的檔案,檔案上的貼上位不起作用。

      當建立檔案或目錄時,擁有者為執行客戶端程序的使用者,組為父目錄所屬的組。每個訪問HDFS的客戶端程序有一個由使用者姓名和組列表兩部分組的成標識,無論何時HDFS必須對由客戶端程序訪問的檔案或目錄進行許可權檢查,規則如下:

如果程序的使用者名稱匹配檔案或目錄的擁有者,那麼測試擁有者許可權
否則如果檔案或目錄所屬的組匹配組列表中任何組,那麼測試組許可權
否則測試其它許可權
      如果許可權檢查失敗,則客戶端操作失敗。

      從hadoop-0.22開始,hadoop支援兩種不同的操作模式以確定使用者,分別為simple和kerberos具體使用哪個方式由引數hadoop.security.authentication設定,該引數位於core-site.xml檔案中,預設值為simple。在simple模式下,客戶端程序的身份由主機的作業系統確定,比如在類Unix系統中,使用者名稱為命令whoami的輸出。在kerberos模式下,客戶端程序的身份由Kerberos憑證確定,比如在一個Kerberized環境中,使用者可能使用kinit工具得到了一個Kerberos ticket-granting-ticket(TGT)且使用klist確定當前的principal。當對映一個Kerberosprincipal到HDFS的使用者名稱時,除了最主要的部分外其餘部分都被丟棄,比如一個principal為todd/

[email protected],將對映為HDFS上的todd。無論哪種操作模式,對於HDFS來說使用者標識機制都是外部的,HDFS本身沒有建立使用者標,建立組或者處理使用者憑證的規定。

      上面討論了確定使用者的兩種模式,即simple和kerberos,下面學習如何確定使用者組。使用者組是通過由引數hadoop.security.group.mapping設定的組對映服務確定的,預設實現是org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback,該實現首先確定Java本地介面(JNI)是否可用,如果JNI可用,該實現將使用hadoop中的API為使用者解析使用者組列表。如果JNI不可用,那麼使用ShellBasedUnixGroupsMapping,該實現將使用Linux/Unix中的bash –cgroups命令為使用者解析使用者組列表。其它實現還有LdapGroupsMapping,通過直接連線LDAP伺服器來解析使用者組列表。對HDFS來說,使用者到組的對映是在NameNode上執行的,因而NameNode的主機系統配置決定了使用者的組對映。HDFS將檔案或目錄的使用者和組儲存為字串,並且不像Linux/Unix那樣可以將使用者和組轉換為數字。

      每個針對檔案或者目錄的操作都將全路徑名稱傳遞到NameNode,然後對該路徑的每次操作都將應用許可權檢查。客戶端隱含地關聯使用者身份到NameNode的連線,減少改變現存客戶端API的需要。總是存在這麼一種情景,當在一個檔案上的操作成功後,當重複該操作時可能失敗,因為該檔案或者路徑中的某些目錄已經不再存在。例如,當客戶端第一次開始讀取一個檔案時,它向NameNode發出的第一個請求來發現該檔案第一個塊的位置,第二個尋找其他塊的請求可能失敗。另一方面,對於已經知道檔案塊的客戶端來說,刪除檔案不會取消訪問。通過新增許可權,客戶端對檔案的訪問在請求之間可能撤回,對於已經知道檔案塊的客戶端來說,改變許可權不會取消客戶端的訪問。

      HDFS中超級使用者與通常熟悉的Linux或Unix中的root使用者不同,HDFS的超級使用者是與NameNode程序有相同標示的使用者,更簡單易懂些,啟動NameNode的使用者就為超級使用者。對於誰是超級使用者沒有固定的定義,當NameNode啟動後,該程序的標示決定了誰是超級使用者。HDFS的超級使用者不必是NameNode主機的超級使用者,也需用所有的叢集使用相同的超級使用者,出於實驗目的在個人工作站上執行HDFS的人自然而然的稱為超級使用者而不需要任何配置。另外引數dfs.permissions.superusergroup設定了超級使用者,該組中的所有使用者也為超級使用者。超級使用者在HDFS中可以執行任何操作而針對超級使用者的許可權檢查永遠不會失敗。

      HDFS也提供了對POSIX ACL(訪問控制列表)支援來為特定的使用者或者使用者組提供更加細粒度的檔案許可權。ACL是不同於使用者和組的自然組織層次的有用的許可權控制方式,ACL可以為特定的使用者和組設定不同的許可權,而不僅僅是檔案的擁有者和檔案所屬的組。預設情況下,HDFS禁用ACL,因此NameNode禁止ACL的建立,為了啟用ACL,需要在hdfs-site.xml中將引數dfs.namenode.acls.enabled設定為true。

      訪問控制列表由一組ACL項組成,每個ACL項命名了特定的使用者或組,併為其授予或拒絕讀,寫和執行的許可權,例如:

user::rw-
user:bruce:rwx                  #effective:r--
group::r-x                      #effective:r--
group:sales:rwx                 #effective:r--
mask::r--
other::r--


      每個ACL項由型別,可選的名稱和許可權字串組成,它們之間使用冒號(:)。在上面的例子中檔案的擁有者具有讀寫許可權,檔案所屬的組具有讀和執行的許可權,其他使用者具有讀許可權,這些設定與將檔案設定為654等價(6表示擁有者的讀寫許可權,5表示組的讀和執行許可權,4表示其他使用者的讀許可權)。除此之外,還有兩個擴充套件的ACL項,分別為使用者bruce和組sales,並都授予了讀寫和執行的許可權。mask項是一個特殊的項,用於過濾授予所有命名使用者,命名組及未命名組的許可權,即過濾除檔案擁有者和其他使用者(other)之外的任何ACL項。在該例子中,mask值有讀許可權,則bruce使用者、sales組和檔案所屬的組只具有讀許可權。每個ACL必須有mask項,如果使用者在設定ACL時沒有使用mask項,一個mask項被自動加入到ACL中,該mask項是通過計算所有被mask過濾項的許可權與(&運算)得出的。對擁有ACL的檔案執行chmod實際改變的是mask項的許可權,因為mask項扮演的是過濾器的角色,這將有效地約束所有擴充套件項的許可權,而不是僅改變組的許可權而可能漏掉其它擴充套件項的許可權。

      訪問控制列表和預設訪問控制列表存在著不同,前者定義了在執行許可權檢查實施的規則,後者定義了新檔案或者子目錄建立時自動接收的ACL項,例如:

user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:bruce:rwx          #effective:r-x
default:group::r-x
default:group:sales:rwx         #effective:r-x
default:mask::r-x
default:other::r-x

      只有目錄可能擁有預設訪問控制列表,當建立新檔案或者子目錄時,自動拷貝父輩的預設訪問控制列表到自己的訪問控制列表中,新的子目錄也拷貝父輩預設的訪問控制列表到自己的預設訪問控制列表中。這樣,當建立子目錄時預設ACL將沿著檔案系統樹被任意深層次地拷貝。在新的子ACL中,準確的許可權由模式引數過濾。預設的umask為022,通常新目錄許可權為755,新檔案許可權為644。模式引數為未命名使用者(檔案的擁有者),mask及其他使用者過濾拷貝的許可權值。在上面的例子中,建立許可權為755的子目錄時,模式對最終結果沒有影響,但是如果建立許可權為644的檔案時,模式過濾器導致新檔案的ACL中檔案擁有者的許可權為讀寫,mask的許可權為讀以及其他使用者許可權為讀。mask的許可權意味著使用者bruce和組sales只有讀許可權。拷貝ACL發生在檔案或子目錄的建立時,後面如果修改父輩的預設ACL將不再影響已存在子類的ACL。

      預設ACL必須包含所有最小要求的ACL項,包括檔案擁有者項,檔案所屬的組項和其它使用者項。如果使用者沒有在預設ACL中配置上述三項中的任何一個,那麼該項將通過從訪問ACL拷貝對應的許可權來自動插入,或者如果沒有訪問ACL則自動插入許可權位。預設ACL也必須擁有mask,如果mask沒有被指定,通過計算所有被mask過濾項的許可權與(&運算)自動插入mask。當一個檔案擁有ACL時,許可權檢查的演算法變為:

如果使用者名稱匹配檔案的擁有者,則測試擁有者許可權

  • 否則,如果使用者名稱匹配命名使用者項中的使用者名稱,則測試由mask許可權過濾後的該項的許可權
  • 否則,如果檔案所屬的組匹配組列表中的任何組,並且如果這些被mask過濾的許可權具有訪問許可權,那麼使用這麼許可權
  • 否則,如果存在命名組項匹配組列表中的成員,並且如果這些被mask過濾的許可權具有訪問許可權,那麼使用這麼許可權
  • 否則,如果檔案所屬的組或者任何命名組項匹配組列表中的成員,但不具備訪問許可權,那麼訪問被拒絕
  • 否則測試檔案的其他使用者許可權

2.hadoop許可權控制

  上文的acl細粒度控制其實我也沒看很懂,不過這裡要做的多租戶隔離暫時只需要粗粒度的許可權控制即可,所以複習一下unix的POSIX系統許可權模型就好

  預設許可權控制配置在hadoop的core-site.xml中,"fs.permissions.umask-mode"值預設為022,umask是表示反碼的意思,022是代表你在建檔案時候,系統自動用777去跟022相減得到755,你的檔案就是755的許可權,顯示出來就是wrxw-xw-x,檔案所有者有讀、寫、執行;組成員有讀、執行,其他人員有讀、執行許可權。linux中的umask引數是八進位制,而hadoop中類似作用的引數採用的是十進位制,這樣想要寫入的檔案許可權為rwxr-x---(750),linux中umask需設為027,對應的十進位制為2*8+7=23,所以將dfs.umask引數設為023,即可達到目的。(我看網上有些人說用八進位制配置並不能生效,試一下轉十進位制)

  • 1、訪問某個路徑時,使用者必須具備該路徑上每個目錄的執行(x)許可權,路徑中最後一個目錄/檔案除外。例如 ls /user/foo/data操作要求使用者必須具有根目錄(/),user目錄,foo目錄的執行許可權。
  • 2、建立一個檔案或者目錄時,owner是客戶程序的使用者,group則繼承父目錄
  • 3、新建檔案或目錄的模式(mode)由client在rpc呼叫時傳遞給NameNode,它受配置引數umask的約束。新檔案的模式是666 & ^umask,新目錄的模式是777 & ^umask,即檔案預設是沒有執行(x)許可權的。如果在 create(path, permission, …) 方法中指定了許可權引數P,新檔案的模式是P & ^umask & 666,如果在mkdirs(path, permission ) 方法中指定了許可權引數P,新目錄的模式是P & ^umask & 777。
  • 例1:如果umask是022(預設值),那麼新檔案的模式就是644,新目錄的模式就是755,即umask擦除掉了group和other的寫許可權。
  • 例2:如果umask是027,那麼新檔案的模式就是650,新目錄的模式就是750,即umask擦除掉了group的寫許可權,以及other的讀寫執行許可權。
  • 4、umask通過client端hdfs-site.xml中的fs.permissions.umask-mode配置項來指定,預設是022。
  • 5、只有超級使用者才可以呼叫chown來修改目錄和檔案的owner。

備註:為特定的使用者和組提供細緻粒度的許可權管理, 而不只是owner,group。該功能預設關閉, 需要如下設定開啟,具體配置實在hdfs-site.xml中:

<property> 
<name>dfs.permissions.enabled</name> 
<value>true</value> 
</property>


<property> 
<name>dfs.namenode.acls.enabled</name> 
<value>true</value> 
</property>

3.新建使用者操作HDFS

  新建hadoop使用者組下的使用者後執行hadoop命令即可以擁有使用者特有的目錄,與linux使用者系統一樣.

  由於專案有更高階的要求,所以這份資料先了解到這裡, 準備開啟kerberos來啟動hdfs多租戶功能,下篇文章再見