金融データ分析基盤の構築 - Hadoop(3)
前回:
今回やること
Hadoopクラスタ用プリンシパルの作成
HadoopクラスタのKerberos連携
各ノードのKerberos設定
Hadoopクラスタの確認
1. Hadoopクラスタ用プリンシパルの作成
まずは、Hadoopクラスタの各ノードが使うためのプリンシパルを作成する。Kerberos認証を用いる場合はクラスタのノード間でも認証が必要となるため、ユーザではなくサービスのプリンシパルをいくつか作ることになる。
基本的には以下のドキュメント通りにプリンシパルを作る。
一部引用してくると、NameNode用のプリンシパルはこんな感じ。
$ klist -e -k -t /etc/security/keytab/nn.service.keytab
Keytab name: FILE:/etc/security/keytab/nn.service.keytab
KVNO Timestamp Principal
4 07/18/11 21:08:09 nn/full.qualified.domain.name@REALM.TLD (AES-256 CTS mode with 96-bit SHA-1 HMAC)
4 07/18/11 21:08:09 nn/full.qualified.domain.name@REALM.TLD (AES-128 CTS mode with 96-bit SHA-1 HMAC)
4 07/18/11 21:08:09 nn/full.qualified.domain.name@REALM.TLD (ArcFour with HMAC/md5)
4 07/18/11 21:08:09 host/full.qualified.domain.name@REALM.TLD (AES-256 CTS mode with 96-bit SHA-1 HMAC)
4 07/18/11 21:08:09 host/full.qualified.domain.name@REALM.TLD (AES-128 CTS mode with 96-bit SHA-1 HMAC)
4 07/18/11 21:08:09 host/full.qualified.domain.name@REALM.TLD (ArcFour with HMAC/md5)
手順は、以下のコマンドでKerberosの管理サーバに対してリクエストを送る。
$ kadmin.local
$ addprinc -randkey nn/<FQDN>@REALM
$ addprinc -randkey host/<FQDN>@REALM
$ ktadd -e aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96,rc4-hmac:normal -k /etc/security/keytabs/nn.keytab nn/<FQDN>@REALM
上記で生成したKeytabファイルはパスワードなしでログイン可能なように認証情報が含まれている。これらを適切な所有者・グループ・権限にして、各ノードに配置する。(上記はNameNodeのみだが、Secondary NameNode、DataNodeに対しても行う。)
2. HadoopクラスタのKerberos連携
Hadoopクラスタ用のプリンシパルは作れたので、それらのプリンシパルを使って認証するようにKerberosの設定をする。設定は、各ノードの以下のファイルを編集する。
core-site.xml
hdfs-site.xml
ssl-server.xml(HTTPS必須だったためとりあえず設定)
# core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop-namenode1.home:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop/tmp</value>
</property>
<property>
<name>hadoop.rpc.protection</name>
<value>authentication</value>
</property>
<property>
<name>hadoop.security.authentication</name>
<value>kerberos</value>
</property>
<property>
<name>hadoop.security.authorization</name>
<value>true</value>
</property>
<property>
<name>hadoop.security.auth_to_local</name>
<value>
RULE:[2:$1/$2@$0]([ndj]n/.*@HOME)s/.*/hdfs/
RULE:[2:$1/$2@$0]([rn]m/.*@HOME)s/.*/yarn/
RULE:[2:$1/$2@$0](jhs/.*@HOME)s/.*/mapred/
DEFAULT
</value>
</property>
</configuration>
# hdfs-site.xml (NameNodeのもの)
<configuration>
<property>
<name>dfs.block.access.token.enable</name>
<value>true</value>
</property>
<property>
<name>dfs.namenode.kerberos.principal</name>
<value>nn/_HOST@HOME</value>
</property>
<property>
<name>dfs.namenode.keytab.file</name>
<value>/etc/security/keytab/nn.service.keytab</value>
</property>
<property>
<name>dfs.namenode.kerberos.internal.spnego.principal</name>
<value>HTTP/_HOST@HOME</value>
</property>
<property>
<name>dfs.web.authentication.kerberos.keytab</name>
<value>/etc/security/keytab/spnego.service.keytab</value>
</property>
<property>
<name>dfs.http.policy</name>
<value>HTTPS_ONLY</value>
</property>
<property>
<name>dfs.data.transfer.protection</name>
<value>authentication</value>
</property>
</configuration>
# ssl-server.xml
<configuration>
<property>
<name>ssl.server.truststore.location</name>
<value>/etc/ssl/hadoop/mykeystore.jks</value>
</property>
<property>
<name>ssl.server.truststore.password</name>
<value>storepassword</value>
</property>
<property>
<name>ssl.server.truststore.type</name>
<value>jks</value>
</property>
<property>
<name>ssl.server.truststore.reload.interval</name>
<value>10000</value>
</property>
<property>
<name>ssl.server.keystore.location</name>
<value>/etc/ssl/hadoop/mykeystore.jks</value>
</property>
<property>
<name>ssl.server.keystore.password</name>
<value>storepassword</value>
</property>
<property>
<name>ssl.server.keystore.keypassword</name>
<value>keypassword</value>
</property>
<property>
<name>ssl.server.keystore.type</name>
<value>jks</value>
</property>
<property>
<name>ssl.server.exclude.cipher.list</name>
<value>TLS_ECDHE_RSA_WITH_RC4_128_SHA,SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
SSL_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA,
SSL_RSA_EXPORT_WITH_RC4_40_MD5,SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
SSL_RSA_WITH_RC4_128_MD5</value>
</property>
</configuration>
設定はドキュメントのセキュリティのページに書いてあるのだが、ドキュメントだけではちょっとよくわからない部分もあった。そこで色々試行錯誤していて時間がかかってしまった。
dfs.block.access.token.enableについて
ドキュメントには、NameNodeの設定のほうにdfs.block.access.token.enableをtrueにするようにと書いてあるが、これはDataNodeの設定にも必要となっていた。
これをDataNodeで有効にしておかないと、「セキュリティの設定されてるのに、Block Access Tokenが有効になってないよ」というようなエラーが出てしまう。
HTTPS_ONLYとその他の設定
ドキュメントには、DataNodeのセキュリティについて以下のように書かれている。
Hadoopのバージョン2.6.0以降ではSASLを利用できるらしく、その利用方法としては非特権ポートの設定をし、HTTPではなくHTTPS通信のみを利用するように設定する必要がある。
そうしないと、ソースの以下の部分で例外が投げられてしまうようになっている(Incorrect config的な感じの)
HTTPS通信のみにすると当然だがサーバ側のSSL設定をしなくてはいけなくなる。なので、とりあえず自己証明書を適当に作って設定のみしてある。
3. 各ノードのKerberos設定
あと、Hadoopクラスタの各ノードのKerberos設定が必要になってくる。KDCサーバをLAN内に立てているが、そもそも各ノードのクライアントに適切なレルムの設定(特にデフォルトレルム)をしないとうまく認証ができなかった。
各ノードには以下のような感じで、デフォルトレルムを設定しておかないと、Hadoop内でTGS要求を行ったりする際にうまくできなかったりしていたっぽい(ログを見る限り)。
[libdefaults]
default_realm = HOME
kdc_timesync = 1
ccache_type = 4
forwardable = true
proxiable = true
rdns = false
fcc-mit-ticketflags = true
[realms]
HOME = {
kdc = kdc.home
admin_server = kdc.home
}
4. Hadoopクラスタの確認
それらの設定をしてNameNodeでsbin/start-dfs.shを実行する。その後まずログを確認してサーバがエラーなどでシャットダウンしてないかをみて、特に問題なさそうだったらNameNodeの指定したポートにHTTPSでアクセスすると管理画面が見える。
Live Nodesが1となっているので、DataNodeが一つ正常に接続できていることがわかる。また、CapacityもDataNodeのストレージひとつ分の容量があることが確認できた。
ぼやき
認証周りで結構時間かかって、とりあえず動いた感じだけど、ちゃんと理解できているかは少し怪しい。次の記事でYARNなどに行く前にHadoopの認証を図解したりより詳しく理解するための内容を書こうかな。
特に、SASLやSPNEGOあたりや、認証の具体的な手順などについて知りたい。あと、それらに問題が合った時の調べたかなど。
次やること
認証のより詳しい理解
YARNのセットアップ
MapRecudeのセットアップ
HDFS、YARN、MapRecudeの設定を詳しく理解する
この記事が気に入ったらサポートをしてみませんか?