Hadoop-1.1.2を完全分散モードで動作させるまでの設定

CentOS6にHadoop-1.1.2を設定したのでその時のメモを記載します。
以下の手順は完全分散モードで動作するように設定を行った手順になります。[ ]はそれぞれの環境に合わせて調整してください。
ここでは、SELinuxはtargetedでファイアウォールiptables)は有効にしたままで動作する手順を紹介します。(ちなみにIPv6は無効)

■全環境でユーザ作成とHadoopのインストール、各種設定を実施

hadoopユーザの作成


groupadd hadoop
useradd -g hadoop hadoop
passwd hadoop

hadoop-1.1.2.tar.gzを解凍しオーナをhadoopに設定した後、シンボリックリンクを作成。


cd [path_to_install_dir]
tar -zxvf hadoop-1.1.2.tar.gz
chown -R hadoop:hadoop hadoop-1.1.2/
ln -s hadoop-1.1.2/ hadoop

hadoopユーザにsuしJAVA_HOME、HADOOP_HOMEの設定を行う。


vi .bash_profile
JAVA_HOME=[path_to_jdk]
HADOOP_HOME=[path_to_hadoop_home]
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME
export HADOOP_HOME
export PATH

Hadoopの設定

$HADOOP_HOME/conf/core-site.xmlの設定

<configuration>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>[path_to_hadoop_tmp_dir]</value>
    </property>
    <property>
        <name>fs.default.name</name>
        <value>hdfs://[master_host_name]:[port]</value>
    </property>
</configuration>

$HADOOP_HOME/conf/hdfs-site.xmlの設定

<configuration>
    <property>
        <name>dfs.name.dir</name>
        <value>${hadoop.tmp.dir}/dfs/name</value>
    </property>
    <property>
        <name>dfs.data.dir</name>
        <value>${hadoop.tmp.dir}/dfs/data</value>
    </property>
</configuration>

$HADOOP_HOME/conf/mapred-site.xmlの設定

<configuration>
    <property>
        <name>mapred.job.tracker</name>
        <value>[master_host_name]:[port]</value>
    </property>
</configuration>

$HADOOP_HOME/conf/hadoop-env.shの設定


export JAVA_HOME=[path_to_jdk]
export HADOOP_PID_DIR=[path_to_hadoop_pid_dir] #デフォルトでも良いが、他のサービスに習って/var/run/配下にhadoop用のディレクトリを作成するほうがわかりやすい?

ルートユーザでデータディレクトリとPIDファイル格納ディレクトリを作成


mkdir [path_to_hadoop_tmp_dir]
chown -R hadoop:hadoop [path_to_hadoop_tmp_dir]
mkdir [path_to_hadoop_pid_dir]
chown -R hadoop:hadoop [path_to_hadoop_pid_dir]

■マスタノードでhadoopユーザでssh用の公開キーを作成し各ノードに配布する


ssh-keygen -t rsa -P ""
cd .ssh
cat id_rsa.pub >> authorized_keys
chmod 600 authorized_keys

完全にローカルなネットワーク内であれば上記のような空パスフレーズを設定しても問題ないのですが、そうでない場合はセキュリティ上の問題が発生します。
何か適当なパスフレーズを設定し、毎回ssh-agentを起動してパスフレーズをキャッシュするのもいいのですが、今回はPAMを利用してhadoopユーザでssh可能なホストに制限をかける方法を紹介します。

SSHでPAM認証を利用するように設定し、hadoopユーザによるssh接続はマスタノードの場合は自ノードのみ、スレーブノードの場合はマスタノード及び、自ノードのみからアクセス可能にする。


cd /etc/security
vi access.conf
- : hadoop : ALL EXCEPT [マスタノードのIP] 127.0.0.1 [自ノードのIP(スレーブノードの場合のみ)] #定義追加

vi /etc/pam.d/sshd
account required pam_access.so shadow nullok #定義追加

cd /etc/ssh
vi sshd_config
#PermitEmptyPasswords no

PermitEmptyPasswords yes

UsePAM no

UsePAM yes

こうすることで多少セキュリティは向上すると思います。

なお、tcpwrapperを利用しhosts.denyですべて拒否し、hosts.allowで特定のネットワークおよび、サービスに対する制御を行っている場合、少なくともhosts.allowファイル内にsshdのサービスにlocalhostからの接続を許可するように設定する必要があります。
理由はマスタ側でhadoop起動時にセカンダリのNameNodeを起動する際にHadooplocalhostに対してsshログインを行いセカンダリの起動を行っているようなので、localhostを定義していないとサーバ側で接続が拒否されてしまうからです。


vi /etc/hosts.allow
sshd : [xxx.yyy.zzz.] localhost
or
ALL : [xxx.yyy.zzz.] localhost #簡単に設定するならこちらだが・・・

上記作業が各ノードで完了したらsshdを再起動し、マスタノードで作成した公開キーを各スレーブノードに登録しまます。


service sshd restart

公開キーを各ノードに登録する。


ssh-copy-id -i .ssh/id_rsa.pub hadoop@[slave_node1]
ssh-copy-id -i .ssh/id_rsa.pub hadoop@[slave_node2]
...

■マスターノードのiptablesにとりあえず最低限以下の定義を追加しiptablesを再起動


vi /etc/sysconfig/iptables
-A INPUT -s [ローカルネットワーク]/24 -p tcp -m state --state NEW -m tcp --dport [fs.default.name用のポート] -j ACCEPT
-A INPUT -s [ローカルネットワーク]/24 -p tcp -m state --state NEW -m tcp --dport [mapred.job.tracker用のポート] -j ACCEPT

service iptables restart

■スレーブノードのiptablesにとりあえず最低限以下の定義を追加しiptablesを再起動


vi /etc/sysconfig/iptables
-A INPUT -s [ローカルネットワーク]/24 -p tcp -m state --state NEW -m tcp --dport [dfs.datanode.address用のポート(デフォルト:50010)] -j ACCEPT
-A INPUT -s [ローカルネットワーク]/24 -p tcp -m state --state NEW -m tcp --dport [dfs.datanode.ipc.address用のポート(デフォルト:50020)] -j ACCEPT
-A INPUT -s [ローカルネットワーク]/24 -p tcp -m state --state NEW -m tcp --dport [dfs.datanode.http.address用のポート(デフォルト:50075)] -j ACCEPT
-A INPUT -s [ローカルネットワーク]/24 -p tcp -m state --state NEW -m tcp --dport [mapred.task.tracker.http.address用のポート(デフォルト:50060)] -j ACCEPT

service iptables restart

■マスターノードの$HADOOP_HOME/conf/slavesにslaveノードのホスト名を設定する


cd $HADOOP_HOME/conf
vi slaves
slave_node1
slave_node2
...

■NameNodeのフォーマット処理を行い、hadoopクラスタを起動


cd $HADOOP_HOME/bin
./hadoop namenode -format
./start-all.sh

hadoopユーザでHADOOP_HOMEを設定しているため、HADOOP_HOME環境変数は非推奨云々の警告が出ますが、とりあえず動作上は問題なさそうです。
(0.20のころは出てなかった気がするが、長い間使ってなかったんでいつの間にか変わった?)

ブラウザでhadoopのWeb管理画面(http://[master]:50070)にアクセスし、各ノードが起動されているか確認できます。
念のため各ノードのログファイルも参照しエラーが発生していないか確かめたほうがいいと思います。

マスタノードではNameNode、SecondaryNameNode、JobTrackerの3プロセスが、スレーブノードではDataNode、TaskTrackerの2プロセスが起動すればまずは問題ないと思います。

停止する場合は以下のコマンドで停止させるのが簡単です。


cd $HADOOP_HOME/bin
./stop-all.sh

これで準備完了です。あとはファイルディスクリプタの設定(/etc/security/limits.conf)やカーネルパラメータのチューニング(/etc/sysctl.conf)など、必要に応じて行えばいいと思います。

この辺についてはいろいろなサイトや、書籍を参考にすればいいので省略します。

なお、sshのアクセス制御などセキュリティにかかわる設定が関係しているため、参考にする場合は利用する環境に合わせて自己責任でお願いします。
(結構面倒なので完全にプライベートなネットワークで動作させることをおススメします。)