ユーザーのグループは、グループマッピングサービスプロバイダーによって決定されます。 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が使用できない場合は、シェルベースの実装である`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で従来のように、ユーザーとグループのID番号からの変換はありません。
`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に設定します。 これにより、デフォルトで3つのスレッドを持つ`hadoop.security.groups.cache.background.reload.threads`スレッドの小さなスレッドプールが有効になります。 この設定では、期限切れのエントリについてキャッシュが照会されると、期限切れの結果がすぐに返され、バックグラウンドでキャッシュを更新するタスクがキューに入れられます。 バックグラウンドの更新に失敗した場合、キャッシュへの次のリクエストによって新しい更新操作がキューに入れられます。 `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 グループ解決クエリを実行できます。
接続を保護するために、実装では SSL 経由の LDAP(LDAPS)がサポートされています。SSL は、hadoop.security.group.mapping.ldap.ssl
を true
に設定することで有効になります。さらに、SSL 接続用のキーストアファイルへのパスを hadoop.security.group.mapping.ldap.ssl.keystore
に、キーストアのパスワードを hadoop.security.group.mapping.ldap.ssl.keystore.password
に指定し、同時に hadoop.security.credential.clear-text-fallback
が true であることを確認してください。または、キーストアのパスワードをファイルに保存し、hadoop.security.group.mapping.ldap.ssl.keystore.password.file
をそのファイルに指定します。セキュリティ上の理由から、このファイルはデーモンを実行している Unix ユーザーのみが読み取り可能である必要があり、再帰的な依存関係を防ぐために、このファイルはローカルファイルである必要があります。 hadoop.security.group.mapping.ldap.ssl.keystore.password
を使用する最初のアプローチは、構成ファイルにパスワードが公開されるため、強くお勧めしません。
通常、Hadoop は 2 つの LDAP クエリを実行することでユーザーのグループ名を解決します。最初のクエリはユーザーオブジェクトを取得し、2 番目のクエリはユーザーの識別名を使用してグループを見つけます。 Active Directory などの一部の LDAP サーバーでは、最初のクエリで返されるユーザーオブジェクトには、memberOf
属性にユーザーのグループの DN も含まれており、グループの名前はその相対識別名です。したがって、2 番目のクエリを送信せずに最初のクエリからユーザーのグループを推測することができ、2 番目のクエリによって発生するグループ名解決レイテンシを削減できます。グループ名を取得できない場合は、一般的な 2 クエリシナリオにフォールバックし、2 番目のクエリを送信してグループ名を取得します。この機能を有効にするには、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 サーバーの構成を示しています。さらに、失敗する前に合計 6 回の試行が行われ、次のサーバーにフェイルオーバーする前に、各サーバーで 2 回の試行が行われます。
<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
の場合、すべてプロバイダーによって返されたグループをマージします。そうでない場合は、最初に成功したプロバイダーのグループを返します。設定例については、次のセクションを参照してください。
この例は、Hadoop 認証が AD レルムを信頼する MIT Kerberos を使用する CompositeGroupsMapping
の一般的なユースケースを示しています。この場合、hdfs、mapred、hbase、hive、oozie などの serviceprincipal は MIT Kerberos に配置できますが、エンドユーザーは信頼された AD からのものです。 serviceprincipal の場合は、効率のために ShellBasedUnixGroupsMapping
プロバイダーを使用してグループを照会でき、エンドユーザーの場合は LdapGroupsMapping
プロバイダーを使用できます。これにより、LdapGroupsMapping
プロバイダーのみを使用する場合に、serviceprincipal のグループエントリを AD に追加する必要がなくなります。複数の AD が関係し、MIT Kerberos によって信頼されている場合は、AD 固有の異なる構成で LdapGroupsMapping
プロバイダーを複数回使用できます。このサンプルでは、その方法も示しています。必要な構成は次のとおりです。
<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 などの他のプロパティも構成する必要があります。