(這部份內容參考成品 https://blog.csdn.net/skywalker_only/article/details/40709447)node
以前在論壇看到一個關於HDFS權限的問題,當時沒法回答該問題。沒法回答並不意味着對HDFS權限一無所知,而是不能準確完整的闡述HDFS權限,所以決定系統地學習HDFS文件權限。HDFS的文件和目錄權限模型共享了POSIX(Portable Operating System Interface,可移植操做系統接口)模型的不少部分,好比每一個文件和目錄與一個擁有者和組相關聯,文件或者目錄對於擁有者、組內的其它用戶和組外的其它用戶有不一樣的權限等。與POSIX模型不一樣的是,HDFS中的文件沒有可執行文件的概念,於是也沒有setuid和setgid,雖然目錄依然保留着可執行目錄的概念(x),但對於目錄也沒有setuid和setgid。粘貼位(sticky bit)能夠用在目錄上,用於阻止除超級用戶,目錄或文件的擁有者外的任何刪除或移動目錄中的文件,文件上的粘貼位不起做用。linux
當建立文件或目錄時,擁有者爲運行客戶端進程的用戶,組爲父目錄所屬的組。每一個訪問HDFS的客戶端進程有一個由用戶姓名和組列表兩部分組的成標識,不管什麼時候HDFS必須對由客戶端進程訪問的文件或目錄進行權限檢查,規則以下:算法
若是進程的用戶名匹配文件或目錄的擁有者,那麼測試擁有者權限
不然若是文件或目錄所屬的組匹配組列表中任何組,那麼測試組權限
不然測試其它權限
若是權限檢查失敗,則客戶端操做失敗。apache
從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/foobar@CORP.COMPANY.COM,將映射爲HDFS上的todd。不管哪一種操做模式,對於HDFS來講用戶標識機制都是外部的,HDFS自己沒有建立用戶標,創建組或者處理用戶憑證的規定。bash
上面討論了肯定用戶的兩種模式,即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發出的第一個請求來發現該文件第一個塊的位置,第二個尋找其餘塊的請求可能失敗。另外一方面,對於已經知道文件塊的客戶端來講,刪除文件不會取消訪問。經過添加權限,客戶端對文件的訪問在請求之間可能撤回,對於已經知道文件塊的客戶端來講,改變權限不會取消客戶端的訪問。app
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。oop
訪問控制列表由一組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時,權限檢查的算法變爲:
若是用戶名匹配文件的擁有者,則測試擁有者權限
上文的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,便可達到目的。(我看網上有些人說用八進制配置並不能生效,試一下轉十進制)
備註:爲特定的用戶和組提供細緻粒度的權限管理, 而不僅是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>
新建hadoop用戶組下的用戶後執行hadoop命令便可以擁有用戶特有的目錄,與linux用戶系統同樣.
因爲項目有更高級的要求,因此這份資料先了解到這裏, 準備開啓kerberos來啓動hdfs多租戶功能,下篇文章再見