ゲートウェイノードまたは Java アプリケーションから HDFS にアクセスするには、Hadoop Auth Server (HAS) Kerberos 認証を使用します。
前提条件
EMR-3.40 以前、または EMR-4.10.1 以前を実行する Hadoop クラスターを作成済みである必要があります。詳細については、「クラスターの作成」をご参照ください。
hadoop コマンドを使用した HDFS へのアクセス
以下の手順では、ユーザー例として test を使用します。
- ゲートウェイノードで krb5.conf ファイルを構成します。
scp root@emr-header-1:/etc/krb5.conf /etc/ - hadoop.security.authentication.use.has パラメーターを false に設定します。
- クラスターの
emr-header-1ノードにログインします。説明 HA クラスターの場合も、emr-header-1ノードにログインする必要があります。詳細については、「クラスターへのログイン」をご参照ください。
- 次のコマンドを実行して core-site.xml ファイルを編集します。
vim /etc/ecm/hadoop-conf/core-site.xml - hadoop.security.authentication.use.has の値を確認します。
- 値が true の場合、hadoop.security.authentication.use.has の値を false に変更します。
- 値が false の場合、ステップ 3 に進みます。
- クラスターの
- プリンシパルを追加します。
- 次のコマンドを実行して Kerberos 管理ツールを起動します。
- EMR-3.30.0 以降および EMR-4.5.1 以降の場合:
sh /usr/lib/has-current/bin/admin-local.sh /etc/ecm/has-conf -k /etc/ecm/has-conf/admin.keytab - EMR-3.30.0 以前および EMR-4.5.1 以前の場合:
sh /usr/lib/has-current/bin/hadmin-local.sh /etc/ecm/has-conf -k /etc/ecm/has-conf/admin.keytab
- EMR-3.30.0 以降および EMR-4.5.1 以降の場合:
- 次のコマンドを実行して
testプリンシパルを追加します。この例では、パスワードを
123456に設定します。addprinc -pw 123456 test - 次のコマンドを実行して keytab ファイルをエクスポートします。
ktadd -k /root/test.keytab test
- 次のコマンドを実行して Kerberos 管理ツールを起動します。
- チケットを取得します。
HDFS コマンドを実行するクライアント(この例ではゲートウェイノード)で、次のコマンドを実行します。
testという名前の Linux アカウントを作成します。useradd test- MIT Kerberos クライアントツールをインストールします。
MIT Kerberos は
kinitやklistなどのコマンドを提供します。詳細については、「MIT Kerberos」をご参照ください。yum install krb5-libs krb5-workstation -y testアカウントに切り替えてkinitを実行します。su test- keytab ファイルがない場合は、
kinitを実行し、プロンプトが表示されたらパスワード123456を入力します。 - keytab ファイルがある場合は、次のコマンドを実行します。
# 指定された keytab ファイル内の指定されたプリンシパルで認証します。 kinit -kt test.keytab test # チケットの有効期間を表示します。 klistklistを実行します。出力例:Valid starting Expires Service principal 03/30/2021 10:48:47 03/31/2021 10:48:47 krbtgt/EMR.209749.COM@EMR.209749.COM renew until 03/31/2021 10:48:47
- keytab ファイルがない場合は、
- オプション: チケットの有効期間を設定するには:
- チケットの有効期間を設定します。
kinit -l 5d klistコマンドを実行してチケットの有効期間を表示します。Valid starting Expires Service principal 03/30/2021 10:50:51 04/04/2021 10:50:51 krbtgt/EMR.209749.COM@EMR.209749.COM renew until 04/01/2021 10:50:51
- チケットの有効期間を設定します。
- ゲートウェイノードで次のコマンドを実行して環境変数を設定します。
export HADOOP_CONF_DIR=/etc/has/hadoop-conf - HDFS コマンドを実行します。
hadoop fs -ls /出力例:Found 6 items drwxr-xr-x - hadoop hadoop 0 2021-03-29 11:16 /apps drwxrwxrwx - flowagent hadoop 0 2021-03-29 11:18 /emr-flow drwxr-x--- - has hadoop 0 2021-03-29 11:16 /emr-sparksql-udf drwxrwxrwt - hadoop hadoop 0 2021-03-29 11:17 /spark-history drwxr-x--- - hadoop hadoop 0 2021-03-29 11:16 /tmp drwxrwxrwt - hadoop hadoop 0 2021-03-29 11:17 /user
Java コードを使用した HDFS へのアクセス
- ローカルチケットキャッシュを使用する場合 説明
kinitを事前に実行してチケットを取得しておく必要があります。チケットの有効期限が切れると、アプリケーションは HDFS にアクセスできなくなります。public static void main(String[] args) throws IOException { Configuration conf = new Configuration(); // HDFS 構成を読み込みます。EMR クラスターから HDFS 構成をコピーする必要があります。 conf.addResource(new Path("/etc/ecm/hadoop-conf/hdfs-site.xml")); conf.addResource(new Path("/etc/ecm/hadoop-conf/core-site.xml")); // Linux アカウントで事前に kinit を実行してチケットを取得しておく必要があります。 UserGroupInformation.setConfiguration(conf); UserGroupInformation.loginUserFromSubject(null); FileSystem fs = FileSystem.get(conf); FileStatus[] fsStatus = fs.listStatus(new Path("/")); for(int i = 0; i < fsStatus.length; i++){ System.out.println(fsStatus[i].getPath().toString()); } } - keytab ファイルを使用する場合(推奨) 説明 keytab ファイルは長期的に有効であり、ローカルチケットに依存しません。
public static void main(String[] args) throws IOException { String keytab = args[0]; String principal = args[1]; Configuration conf = new Configuration(); // HDFS 構成を読み込みます。EMR クラスターから HDFS 構成をコピーする必要があります。 conf.addResource(new Path("/etc/ecm/hadoop-conf/hdfs-site.xml")); conf.addResource(new Path("/etc/ecm/hadoop-conf/core-site.xml")); // EMR クラスターの emr-header-1 ノードから取得した keytab ファイルを使用します。 UserGroupInformation.setConfiguration(conf); UserGroupInformation.loginUserFromKeytab(principal, keytab); FileSystem fs = FileSystem.get(conf); FileStatus[] fsStatus = fs.listStatus(new Path("/")); for(int i = 0; i < fsStatus.length; i++){ System.out.println(fsStatus[i].getPath().toString()); } }次の Maven 依存関係が必要です。<dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>x.x.x</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>x.x.x</version> </dependency> </dependencies>説明x.x.xはご利用のクラスターの Hadoop バージョンに置き換えてください。