hadoop
ClouderaManager

Cloudera Manager API を使ったクラスタ構築

More than 3 years have passed since last update.

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ですが、今はログインする必要はないのでこの画面が見られれば十分です。

01_login.png


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 であればこの設定のままで大丈夫です。


cm_rest.sh

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日間のトライアルを選択します。


cm_rest.sh

# Start Trial

curl -X POST -u "admin:admin" -i $BASE/cm/trial/begin


deploymentへのホストの追加

ちょっと面倒な処理をしていますが、やってることは下記の3つで、自動化するのでなければ2.のみを実行すれば大丈夫です。

1. jsonの配列形式にできる追加するhostのリスト作成

2. リストに対するインストールのkick

3. 2.はインストールが終わらなくてもプロンプトが返ってくるので完了の待機

この処理はagentで使用するパッケージのダウンロード/インストールを行うのでそれなりに時間がかかります。


cm_rest.sh

# 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 を構成します。


cm_rest.sh

## Create mgmt service

curl -X PUT -u "admin:admin" -i \
-H "content-type:application/json" \
-d '{ "name": "mgmt" }' \
$BASE/cm/service


ロールの配置と構成

ロールを配置し、デフォルトの設定を作成します。


cm_rest.sh

## 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という変数に入れて続きを実行してください。


cm_rest.sh

## 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関連のロールは削除しておきます。


cm_rest.sh

## 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の構成になります。


cm_rest.sh

# Startup

curl -X POST -u "admin:admin" -i $BASE/cm/service/commands/start


Clusterの作成

まずは枠としてのClusterを作成します


cm_rest.sh

## 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=...の行のようにして確認することできます。


cm_rest.sh

## 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とつけることも可能です。


cm_rest.sh

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

※コードはイメージです。実際のスクリプトとは異なることがあります。ご了承ください。

上記で実行してしまった方はご愁傷様です。

特に脈絡のない元ネタ



サービスの配置と構成

Management Service同様に実施します。


cm_rest.sh

## 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側で処理が継続するので処理状況を監視しています。


cm_rest.sh

### 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同様に設定が必要なので実施していきます。


cm_rest.sh

## 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を実行していきます。


cm_rest.sh

## FirstRun

curl -X POST -u "admin:admin" -i $BASE/clusters/$CLUSTER/commands/firstRun


構成状況の確認

上記まで実行したところで http://<nodename>:7180 にアクセスし、今度はログインするとサービスの構成状況を確認することができます。

FirstRunはKickしただけでプロンプトが返ってきて、実際の処理はClouderaManager側で継続しています。実行後すぐにアクセスすると少しずつ起動していく様子が見えると思います。


まとめ

いかがでしたでしょうか。GUIでやるとクリックするだけ、というところが多いのに対してCUIのコマンドにすると意識する箇所が多く、大変になった気もしますが、繰り返す環境構築を自動化する際の参考になれば幸いです。