使用者的群組是由群組對應服務提供者所決定。Hadoop 支援各種群組對應機制,透過 hadoop.security.group.mapping
屬性來設定。其中一些,例如 JniBasedUnixGroupsMappingWithFallback
,使用作業系統的群組名稱解析,不需要設定。但 Hadoop 也支援透過 LDAP 和 LDAP 與作業系統群組名稱解析組合的特殊群組對應機制,需要額外的設定。hadoop.security.group.mapping
可以是下列其中之一
org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback
預設的實作。它會判斷 Java Native Interface (JNI) 是否可用。如果 JNI 可用,實作會使用 Hadoop 內的 API 來解析使用者的群組清單。如果 JNI 不可用,則會使用基於 shell 的實作 ShellBasedUnixGroupsMapping
。
org.apache.hadoop.security.JniBasedUnixGroupsNetgroupMappingWithFallback
類似於 JniBasedUnixGroupsMappingWithFallback
。如果 JNI 可用,它會使用 Hadoop 原生 API 取得網路群組成員資格;否則會使用 ShellBasedUnixGroupsNetgroupMapping
。
org.apache.hadoop.security.ShellBasedUnixGroupsMapping
這個實作會使用 bash -c groups
指令(針對 Linux/Unix 環境)或 net group
指令(針對 Windows 環境)來解析使用者的群組清單。
org.apache.hadoop.security.ShellBasedUnixGroupsNetgroupMapping
這個實作類似於 ShellBasedUnixGroupsMapping
,但會執行 getent netgroup
指令來取得網路群組成員資格。
org.apache.hadoop.security.LdapGroupsMapping
一個備用的實作,會直接連線到 LDAP 伺服器來解析群組清單。不過,這個提供者只能在所需的群組完全存在於 LDAP 中,且未在 Unix 伺服器中實體化時使用。LdapGroupsMapping 支援 SSL 連線和 POSIX 群組語意。請參閱 LDAP 群組對應 章節以取得詳細資料。
org.apache.hadoop.security.CompositeGroupsMapping
這個實作會組合其他群組對應提供者來判斷群組成員資格。這允許結合現有的提供者實作,並組合一個虛擬的新提供者,而不需要自訂開發來處理複雜的情況。請參閱 複合群組對應 章節以取得詳細資料。
對於 HDFS,使用者對群組的對應會在 NameNode 上執行。因此,NameNode 的主機系統設定會決定使用者的群組對應。
請注意,HDFS 會將檔案或目錄的使用者和群組儲存為字串;不會像 Unix 中慣例那樣從使用者和群組身分識別號碼轉換。
您可以透過在 hadoop.user.group.static.mapping.overrides
中定義對應,以靜態方式將使用者對應到群組,格式為 user1=group1,group2;user2=;user3=group2
。此屬性會覆寫任何群組對應服務提供者。如果使用者的群組在其中定義,則會在不進行更多查詢的情況下傳回群組;否則,會使用在 hadoop.security.group.mapping
中定義的服務提供者來查詢群組。預設會定義 dr.who=;
,因此虛擬使用者 dr.who 沒有任何群組。
由於群組對應解析依賴於外部機制,因此 NameNode 效能可能會受到影響。為了減少重複查詢造成的影響,Hadoop 會快取服務提供者傳回的群組。快取失效可以透過 hadoop.security.groups.cache.secs
設定,預設為 300 秒。
使用預設快取實作,在 hadoop.security.groups.cache.secs
快取項目過期後,下一個要求群組成員資格的執行緒會查詢群組對應服務提供者,以查詢使用者的目前群組。在執行此查詢時,初始化查詢的執行緒會封鎖,而任何其他要求相同使用者群組的執行緒會擷取先前快取的值。如果重新整理失敗,執行重新整理的執行緒會擲回例外,而程序會在要求查詢該值的下一條執行緒重複。如果查詢重複失敗,且快取未更新,則在 hadoop.security.groups.cache.secs * 10
秒後,快取項目會被驅逐,且所有執行緒會封鎖,直到成功重新載入為止。
若要避免在快取項目過期時任何執行緒封鎖,請將 hadoop.security.groups.cache.background.reload
設為 true。這會啟用一個小型執行緒池,其中包含 hadoop.security.groups.cache.background.reload.threads
執行緒,預設為 3 個執行緒。使用此設定後,當快取查詢過期的項目時,會立即傳回過期的結果,並排隊一項工作,以便在背景中重新整理快取。如果背景重新整理失敗,則快取的下次要求會排隊新的重新整理作業,直到 hadoop.security.groups.cache.secs * 10
,此時快取項目會被驅逐,且所有執行緒會封鎖該使用者,直到成功重新載入為止。
為避免以未知使用者對 NameNode 進行垃圾郵件攻擊,Hadoop 使用負面快取,因此如果查詢結果為空,則直接傳回一個空群組,而不是執行更多群組對應查詢,快取無效化可透過 hadoop.security.groups.negative-cache.secs
進行設定。預設為 30 秒,因此如果群組對應服務提供者未傳回使用者的任何群組,則在 30 秒內不會對同一個使用者執行任何查詢。
此提供者使用 JNDI API 支援具備簡單密碼驗證的 LDAP。必須設定 hadoop.security.group.mapping.ldap.url
。這是用於解析使用者群組的 LDAP 伺服器 URL。它支援透過逗號分隔清單設定多個 LDAP 伺服器。
hadoop.security.group.mapping.ldap.base
設定 LDAP 連線的搜尋基準。這是一個識別名稱,通常會是 LDAP 目錄的根目錄。取得特定使用者名稱的群組會先查詢使用者,然後查詢使用者結果的群組。如果目錄設定有不同的使用者和群組搜尋基準,請使用 hadoop.security.group.mapping.ldap.userbase
和 hadoop.security.group.mapping.ldap.groupbase
設定檔。
在搜尋和等待結果時,可以設定最大時間限制。如果需要無限等待時間,請將 hadoop.security.group.mapping.ldap.directory.search.timeout
設定為 0。預設為 10,000 毫秒 (10 秒)。這是每個 LDAP 查詢的限制。如果 hadoop.security.group.mapping.ldap.search.group.hierarchy.levels
設定為正值,則總延遲時間會受到 max(LDAP 中的遞迴深度,hadoop.security.group.mapping.ldap.search.group.hierarchy.levels
) * hadoop.security.group.mapping.ldap.directory.search.timeout
的限制。
hadoop.security.group.mapping.ldap.base
設定在解析群組時向上移動群組層級的程度。預設限制為 0,為了被視為群組成員,使用者必須是 LDAP 中的明確成員。否則,它會向上移動群組層級 hadoop.security.group.mapping.ldap.search.group.hierarchy.levels
層級。
如果 LDAP 伺服器不支援匿名繫結,請在 hadoop.security.group.mapping.ldap.bind.user
中設定要繫結的使用者識別名稱。包含繫結使用者密碼的檔案路徑會指定在 hadoop.security.group.mapping.ldap.bind.password.file
中。此檔案應僅允許執行守護程式的 Unix 使用者讀取。
如果需要多個繫結使用者,它們可以透過 hadoop.security.group.mapping.ldap.bind.users
指定。這些將表示用於繫結到 LDAP 時要使用的使用者的別名。然後,每個別名都必須設定其識別名稱和密碼。如果繫結使用者的密碼必須重設,這將很有用。如果在連線到 LDAP 時遇到 AuthenticationException,LDAPGroupsMapping 將切換到下一個繫結使用者資訊,並在必要時循環返回。
例如,如果:hadoop.security.group.mapping.ldap.bind.users=alias1,alias2
,則下列設定有效:hadoop.security.group.mapping.ldap.bind.users.alias1.bind.user=bindUser1
hadoop.security.group.mapping.ldap.bind.users.alias1.bind.password.alias=bindPasswordAlias1
hadoop.security.group.mapping.ldap.bind.users.alias2.bind.user=bindUser2
hadoop.security.group.mapping.ldap.bind.users.alias2.bind.password.alias=bindPasswordAlias2
預設設定支援使用 Active Directory 伺服器進行 LDAP 群組名稱解析。
如果 LDAP 伺服器支援 POSIX 群組語意 (RFC-2307),Hadoop 可以透過將 hadoop.security.group.mapping.ldap.search.filter.user
設定為 (&(objectClass=posixAccount)(uid={0}))
,並將 hadoop.security.group.mapping.ldap.search.filter.group
設定為 (objectClass=posixGroup)
,對伺服器執行 LDAP 群組解析查詢。
為了保護連線,此實作支援 LDAP over SSL (LDAPS)。SSL 是透過將 hadoop.security.group.mapping.ldap.ssl
設定為 true
來啟用。此外,在 hadoop.security.group.mapping.ldap.ssl.keystore
中指定 SSL 連線的 keystore 檔案路徑,並在 hadoop.security.group.mapping.ldap.ssl.keystore.password
中指定 keystore 密碼,同時,請確定 hadoop.security.credential.clear-text-fallback
為 true。或者,將 keystore 密碼儲存在檔案中,並將 hadoop.security.group.mapping.ldap.ssl.keystore.password.file
指向該檔案。基於安全性考量,這個檔案應該只能由執行守護程式的 Unix 使用者讀取,且為了防止遞迴相依性,這個檔案應該是一個本機檔案。第一種方法,亦即使用 hadoop.security.group.mapping.ldap.ssl.keystore.password
,極不建議使用,因為它會在設定檔中公開密碼。
通常,Hadoop 會透過兩個 LDAP 查詢來解析使用者的群組名稱:第一個查詢取得使用者物件,第二個查詢使用使用者的識別名稱來尋找群組。對於某些 LDAP 伺服器(例如 Active Directory),第一個查詢中傳回的使用者物件也會包含其 memberOf
屬性中使用者群組的 DN,而群組名稱是其相對識別名稱。因此,有可能從第一個查詢中推斷使用者的群組,而無需傳送第二個查詢,並且可能會減少第二個查詢造成的群組名稱解析延遲。如果無法取得群組名稱,它將會回到典型的兩個查詢場景,並傳送第二個查詢來取得群組名稱。若要啟用此功能,請將 hadoop.security.group.mapping.ldap.search.attr.memberof
設為 memberOf
,Hadoop 將使用使用者物件中的此屬性來解析群組名稱。
如果 LDAP 伺服器的憑證未由知名的憑證授權機構簽署,請在 hadoop.security.group.mapping.ldap.ssl.truststore
中指定信任儲存區的路徑。與金鑰儲存區類似,請在 hadoop.security.group.mapping.ldap.ssl.truststore.password.file
中指定信任儲存區密碼檔。
如果在從 LDAP 伺服器擷取資訊時遇到問題,將會重試要求。若要設定重試次數,請使用下列設定
<name>hadoop.security.group.mapping.ldap.num.attempts</name> <value>3</value> <description> This property is the number of attempts to be made for LDAP operations. If this limit is exceeded, LdapGroupsMapping will return an empty group list. </description> </property>
LDAP 群組對應也支援設定多個 LDAP 伺服器和故障轉移,如果特定執行個體不可用或行為異常。下列設定顯示設定 3 個 LDAP 伺服器。此外,在故障轉移到下一個伺服器之前,將會針對每個伺服器嘗試 2 次,總共嘗試 6 次後才會失敗。
<property> <name>hadoop.security.group.mapping.ldap.url</name> <value>ldap://server1,ldap://server2,ldap://server3</value> <description> The URL of the LDAP server(s) to use for resolving user groups when using the LdapGroupsMapping user to group mapping. Supports configuring multiple LDAP servers via a comma-separated list. </description> </property> <property> <name>hadoop.security.group.mapping.ldap.num.attempts</name> <value>6</value> <description> This property is the number of attempts to be made for LDAP operations. If this limit is exceeded, LdapGroupsMapping will return an empty group list. </description> </property> <property> <name>hadoop.security.group.mapping.ldap.num.attempts.before.failover</name> <value>2</value> <description> This property is the number of attempts to be made for LDAP operations using a single LDAP instance. If multiple LDAP servers are configured and this number of failed operations is reached, we will switch to the next LDAP server. The configuration for the overall number of attempts will still be respected, failover will thus be performed only if this property is less than hadoop.security.group.mapping.ldap.num.attempts. </description> </property>
CompositeGroupsMapping
會透過列舉 hadoop.security.group.mapping.providers
中的服務提供者清單來運作。它會依序從清單中的每個提供者取得群組。如果 hadoop.security.group.mapping.providers.combined
為 true
,請合併所有提供者傳回的群組;否則,傳回第一個成功提供者中的群組。請參閱下列區段以取得範例設定。
此範例說明 CompositeGroupsMapping
的典型使用案例,其中 Hadoop 驗證使用信任 AD 領域的 MIT Kerberos。在這種情況下,服務主體(例如 hdfs、mapred、hbase、hive、oozie 等)可以放置在 MIT Kerberos 中,但最終使用者僅來自受信任的 AD。對於服務主體,可以使用 ShellBasedUnixGroupsMapping
提供者來查詢其群組以提高效率,而對於最終使用者,可以使用 LdapGroupsMapping
提供者。這可以避免僅使用 LdapGroupsMapping
提供者時,在 AD 中新增服務主體的群組項目。如果涉及多個 AD 並受 MIT Kerberos 信任,則可以多次使用 LdapGroupsMapping
提供者,並使用不同的 AD 特定設定。此範例也顯示如何執行此操作。以下是必要的設定。
<name>hadoop.security.group.mapping</name> <value>org.apache.hadoop.security.CompositeGroupsMapping</value> <description> Class for user to group mapping (get groups for a given user) for ACL, which makes use of other multiple providers to provide the service. </description> </property> <property> <name>hadoop.security.group.mapping.providers</name> <value>shell4services,ad4usersX,ad4usersY</value> <description> Comma separated of names of other providers to provide user to group mapping. </description> </property> <property> <name>hadoop.security.group.mapping.providers.combined</name> <value>true</value> <description> true or false to indicate whether groups from the providers are combined or not. The default value is true If true, then all the providers will be tried to get groups and all the groups are combined to return as the final results. Otherwise, providers are tried one by one in the configured list order, and if any groups are retrieved from any provider, then the groups will be returned without trying the left ones. </description> </property> <property> <name>hadoop.security.group.mapping.provider.shell4services</name> <value>org.apache.hadoop.security.ShellBasedUnixGroupsMapping</value> <description> Class for group mapping provider named by 'shell4services'. The name can then be referenced by hadoop.security.group.mapping.providers property. </description> </property> <property> <name>hadoop.security.group.mapping.provider.ad4usersX</name> <value>org.apache.hadoop.security.LdapGroupsMapping</value> <description> Class for group mapping provider named by 'ad4usersX'. The name can then be referenced by hadoop.security.group.mapping.providers property. </description> </property> <property> <name>hadoop.security.group.mapping.provider.ad4usersY</name> <value>org.apache.hadoop.security.LdapGroupsMapping</value> <description> Class for group mapping provider named by 'ad4usersY'. The name can then be referenced by hadoop.security.group.mapping.providers property. </description> </property> <property> <name>hadoop.security.group.mapping.provider.ad4usersX.ldap.url</name> <value>ldap://ad-host-for-users-X:389</value> <description> ldap url for the provider named by 'ad4usersX'. Note this property comes from 'hadoop.security.group.mapping.ldap.url'. </description> </property> <property> <name>hadoop.security.group.mapping.provider.ad4usersY.ldap.url</name> <value>ldap://ad-host-for-users-Y:389</value> <description> ldap url for the provider named by 'ad4usersY'. Note this property comes from 'hadoop.security.group.mapping.ldap.url'. </description> </property>
您還需要設定其他屬性,例如 ldap 提供者的 hadoop.security.group.mapping.ldap.bind.password.file
等,方式與上述相同。