Spark, SQL on Hadoop etc. Advent Calendar 2014 11日目です。
はじめに
Hadoop クラスタの構築は手のかかる作業ですが、Cloudera Managerのようなツールを使えばかなりインストール作業は簡単になります。また、設定なども適宜デフォルトから推奨値に変えてくれたりするので便利です。
ただし、Cloudera ManagerのGUIを使うとインストールは非常に簡単になるのですが、それでも検証などのために環境の作成/削除を繰り返すといった場合、逆にGUI操作が自動化のネックになります。
Cloudera Managerはこの点も考慮していてAPIを公開してCUI処理で代替できるようになっています。
今回はこのCloudera Manager APIを使ったクラスタ構築の簡単なサンプルを紹介します。
前提
CentOS6.5がインストール済み、かつHost Inspectorでひっかかるのでカーネルパラメータvm.swappinessが0になっていることを想定しています。
設定されてなければrootで下記を実行しておいてください。
# echo "vm.swappiness=0" >> /etc/sysctl.conf
# sysctl -p
Cloudera Manager
なにはともあれCloudera Managerのインストールです。
sudo 可能なユーザで下記を実行すればインストールされます。sudoできない場合は最後はsuしてrootで実行してください。
$ curl -O http://archive.cloudera.com/cm5/installer/latest/cloudera-manager-installer.bin
$ chmod 755 cloudera-manager-installer.bin
$ sudo ./cloudera-manager-installer.bin --i-agree-to-all-licenses --noprompt --noreadme
これが終ればブラウザから http://<nodename>:7180
にアクセスすることで Cloudera Manager にアクセスできるようになるはずです。
<nodename>
はインストールしたノードのhostnameを指定してください。インストールノードのブラウザからであれば http://localhost:7180 でOKです。
上記のコマンドが終了してもブラウザからのアクセスに即時応答できず404が返ることがあるのでその場合数分程度待ってみてください。
成功すれば、下記のような画面が見えます。adminユーザの初期パスワードはadminですが、今はログインする必要はないのでこの画面が見られれば十分です。
Cloudera Manager API について
Cloudera Manager API は REST/Python/Java の形式で提供されています。RESTについては(curlコマンドがあれば)インストールなども必要なくすぐに実行できます。
Python と Java のAPIはインストールが必要なので試す場合にはこちらからダウンロードしてセットアップしてください。
今回はREST APIを使って進めていきます。私は今回初めてRESTに触れたので色々と戸惑いましたが今回のサンプルとマニュアルを比較することで他のコマンドについても使い方がなんとなくわかるのではないかと思います。
Cloudera Manager API を使った構成
スクリプト全体はこちらに置いてあります。
以下、bashで実行するコマンドですが、そのままコピペするように先頭のプロンプトは抜いてあります。一箇所sudoしている箇所があるので注意してください。
なお、例外処理などは一切していないので、ネットワークにつながってなかった、などの理由でコマンドが失敗していても終了を待機する箇所の処理は延々と待ち続けることになります。待機処理の中でGETしているコマンドで状況を確認できるので適宜確認してみてください。
環境設定
これはとくにAPIを使うにあたって必須ではないのですが、一部設定を環境変数にして共有してあります。
CMNODEはCloudera Managerを稼動させるノードです。
TARGETはAgentを配置してCloudera Managerで管理するノードになります。space区切りで記載してください。
CLUSTERはClusterの名前です好きにつけてもらって大丈夫です。
各ノードのrootのパスワードを指すROOT_PASSは適宜変更してください。
BASEはバージョン情報(v8)を含むので新しいバージョンを使う場合は変えたのが良いかもしれません。
CDH_VERはCDHのメジャーバージョンです。こちらも新しいバージョンを使う場合には変えることになると思います。
とりあえず、Cloudera Manager 5.2.1/CDH 5.2.1 であればこの設定のままで大丈夫です。
CMNODE="node1.cloudera.com"
TARGET="node1.cloudera.com node2.cloudera.com node3.cloudera.com"
CLUSTER="Cluster1"
ROOT_PASS="cloudera"
BASE=http://$CMNODE:7180/api/v8
CDH_VER=5
とりあえずここまでを設定しておけばsudo可能な環境であれば実行できると思います。
結構時間はかかるので、ダウンロードの上編集して、bash cm_rest.sh
を実行の後続きを読むことをお勧めします。
以下、実行している内容について簡単に説明していきます。
トライアル
ClouderaManagerを使うにはライセンスの選択が必要ですが、今回はセットアップの検証をするだけなので60日間のトライアルを選択します。
# Start Trial
curl -X POST -u "admin:admin" -i $BASE/cm/trial/begin
deploymentへのホストの追加
ちょっと面倒な処理をしていますが、やってることは下記の3つで、自動化するのでなければ2.のみを実行すれば大丈夫です。
- jsonの配列形式にできる追加するhostのリスト作成
- リストに対するインストールのkick
- 2.はインストールが終わらなくてもプロンプトが返ってくるので完了の待機
この処理はagentで使用するパッケージのダウンロード/インストールを行うのでそれなりに時間がかかります。
# Setup Hosts
host_list=""
for i in $TARGET
do
host_list=$host_list'"'$i'"',
done
host_list=${host_list/%?/}
curl -X POST -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "hostNames": ['$host_list'],
"userName" : "root",
"password" : "'$ROOT_PASS'"}' \
$BASE/cm/commands/hostInstall
echo "Waiting for setup nodes"
while [ 1 ]
do
target_size=$(expr 1 + `echo $TARGET | grep -o " " | wc -l`)
installed_hosts=`curl -sS -X GET -u "admin:admin" -i $BASE/hosts | grep '"hostname" :' | wc -l`
test $target_size -eq $installed_hosts && break
echo -e "setuped:" $installed_hosts"/"$target_size"\c"
echo -e "\r\c"
sleep 10
done
最終的には下記のようなコマンド(上記の2.にあたります)を実行して、結果を待つ、ということを意図しています。
curl -X POST -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "hostNames": ["node1.cloudera.com", "node2.cloudera.com", "node3.cloudera.com"],
"userName" : "root",
"password" : "cloudera"}' \
http://$CMNODE:7180/api/v8/cm/commands/hostInstall
これで各ノードがCloudera Managerでの管理下に置かれたことになります。
Management Serviceの設定
クラスタの監視/管理をする Management Service を構成します。
## Create mgmt service
curl -X PUT -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "name": "mgmt" }' \
$BASE/cm/service
ロールの配置と構成
ロールを配置し、デフォルトの設定を作成します。
## Assign and Configure Roles
curl -X PUT -u "admin:admin" -i $BASE/cm/service/autoAssignRoles
curl -X PUT -u "admin:admin" -i $BASE/cm/service/autoConfigure
Report Manager DBの構成
一部のManagement ServiceではLevelDBを使うようになり、RDBMSを使用しなくなっていますが、ReportManagerは引き続きRDBMSを使用しているので構成します。
パスワードは /etc/cloudera-scm-server/db.mgmt.properties にあるので、root権限で取得しています。もしsudoができない場合には先のファイルの com.cloudera.cmf.REPORTSMANAGER.db.passwordエントリから取得し、rman_passという変数に入れて続きを実行してください。
## Setting Report Manager DB
### Report Manager password
rman_pass=`sudo grep com.cloudera.cmf.REPORTSMANAGER.db.password /etc/cloudera-scm-server/db.mgmt.properties | cut -d= -f2`
### Configuration
curl -X PUT -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "items": [{"name": "headlamp_database_host", "value": "'$CMNODE':7432"},
{"name": "headlamp_database_name", "value": "rman"},
{"name": "headlamp_database_password", "value": "'$rman_pass'"},
{"name": "headlamp_database_user", "value": "rman"},
{"name": "headlamp_database_type", "value": "postgresql"}
]}' \
$BASE/cm/service/roleConfigGroups/mgmt-REPORTSMANAGER-BASE/config
使わないロールの削除
今回Navigatorは使わないのでNavigator関連のロールは削除しておきます。
## Delete Navigator Entry
curl -X DELETE -u "admin:admin" -i \
$BASE/cm/service/roles/`curl -sS -X GET -u "admin:admin" -i $BASE/cm/service/roles | grep -B1 '"type" : "NAVIGATORMETASERVER"' | grep name | cut -d'"' -f4`
curl -X DELETE -u "admin:admin" -i \
$BASE/cm/service/roles/`curl -sS -X GET -u "admin:admin" -i $BASE/cm/service/roles | grep -B1 '"type" : "NAVIGATOR"' | grep name | cut -d'"' -f4`
Management Serviceの起動
起動します。ここまででManagement Serviceの構成は終了です。この後はClusterの構成になります。
# Startup
curl -X POST -u "admin:admin" -i $BASE/cm/service/commands/start
Clusterの作成
まずは枠としてのClusterを作成します
## Create Cluster
curl -X POST -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "items": [
{
"name": "'$CLUSTER'",
"version": "CDH'$CDH_VER'"
}
] }' \
$BASE/clusters
ノードをClusterに追加
作成した枠にノードを追加します。Clusterへの追加時にはhostnameではなくhostIdという値を使用します。
これはDeploymentにノードを追加したときに設定されているので下記のhost_ids=...の行のようにして確認することできます。
## Assign Hosts
host_ids=`curl -sS -X GET -u "admin:admin" -i $BASE/hosts | grep '"hostId" :' | cut -d'"' -f 4`
for i in $host_ids
do
curl -X POST -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "items": [ {"hostId": "'$i'"} ]}' \
$BASE/clusters/$CLUSTER/hosts
done
Clusterで稼動させるサービスの選択
typeがサービスの種類です。他のサービスを選択したい場合は一覧を取得するAPIを実行して確認してみてください。
クラスタ上での名前がnameになり、こちらは適当につけられます。下記のようにHIVEサービスにshiumachiとつけることも可能です。
curl -X POST -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "items": [ {"name": "zookeeper", "type": "ZOOKEEPER"},
{"name": "shiumachi", "type": "HIVE"},
{"name": "sqoop" , "type": "SQOOP"},
{"name": "yarn" , "type": "YARN"},
{"name": "hdfs" , "type": "HDFS"}
] }' \
$BASE/clusters/$CLUSTER/servicess
※コードはイメージです。実際のスクリプトとは異なることがあります。ご了承ください。
上記で実行してしまった方はご愁傷様です。
特に脈絡のない元ネタ
しうまちはHiveのように愛されてる. #cwt2014
— Tatsuo Kawasαki (@kernel023) November 6, 2014
サービスの配置と構成
Management Service同様に実施します。
## Assign and Configure Roles
curl -X PUT -u "admin:admin" -i $BASE/clusters/$CLUSTER/autoAssignRoles
curl -X PUT -u "admin:admin" -i $BASE/clusters/$CLUSTER/autoConfigure
Parcelの操作
インストールするCDHのparcelの名前を取得して変数CDHに代入しています。
また、ダウンロード、配布、アクティベートの終了を待つ関数を定義しています。
これらの処理はすぐにプロンプトに返ってきますが、Cloudera Manager側で処理が継続するので処理状況を監視しています。
### Getting CDH Parcel name
CDH=`curl -sS -X GET -u "admin:admin" -i $BASE/clusters/$CLUSTER/parcels | grep -A1 '"product" : "CDH"' | grep '"version" : "'$CDH_VER | cut -d'"' -f4`
### short function to wait previous operation
parcel_wait_for () {
while [ 1 ]
do
curl -sS -X GET -u "admin:admin" -i $BASE/clusters/$CLUSTER/parcels/products/CDH/versions/$CDH | grep '"stage" : "'$1'"' && break
sleep 5
done
}
### Download Parcel
curl -X POST -u "admin:admin" -i $BASE/clusters/$CLUSTER/parcels/products/CDH/versions/$CDH/commands/startDownload
parcel_wait_for DOWNLOADED
### Distribute Parcel
curl -X POST -u "admin:admin" -i $BASE/clusters/$CLUSTER/parcels/products/CDH/versions/$CDH/commands/startDistribution
parcel_wait_for DISTRIBUTED
### Activate Parcel
curl -X POST -u "admin:admin" -i $BASE/clusters/$CLUSTER/parcels/products/CDH/versions/$CDH/commands/activate
parcel_wait_for ACTIVATED
Hive Metastoreの設定
Hive MetastoreもReport Manager同様に設定が必要なので実施していきます。
## Configuring Hive metastore DB
curl -X PUT -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "items": [{"name": "hive_metastore_database_host", "value": "'$CMNODE'"},
{"name": "hive_metastore_database_name", "value": "hive"},
{"name": "hive_metastore_database_password", "value": "hive"},
{"name": "hive_metastore_database_port", "value": "7432"},
{"name": "hive_metastore_database_type", "value": "postgresql"}
]}' \
$BASE/clusters/$CLUSTER/services/hive/config
※HIVEの名前をshiumachiとした場合、$BASE/clusters/$CLUSTER/services/shiumachi/config
に対して実行する必要があります。
FirstRun
各種初期化などを内部的に実行しつつ各サービスを起動するFirstRunを実行していきます。
## FirstRun
curl -X POST -u "admin:admin" -i $BASE/clusters/$CLUSTER/commands/firstRun
構成状況の確認
上記まで実行したところで http://<nodename>:7180
にアクセスし、今度はログインするとサービスの構成状況を確認することができます。
FirstRunはKickしただけでプロンプトが返ってきて、実際の処理はClouderaManager側で継続しています。実行後すぐにアクセスすると少しずつ起動していく様子が見えると思います。
まとめ
いかがでしたでしょうか。GUIでやるとクリックするだけ、というところが多いのに対してCUIのコマンドにすると意識する箇所が多く、大変になった気もしますが、繰り返す環境構築を自動化する際の参考になれば幸いです。