LoginSignup
9
8

More than 5 years have passed since last update.

Apache Zeppelinでデータ分析を分散処理する - Part 2: Ambari on DockerにZeppelinをセットアップする

Last updated at Posted at 2015-12-07

このシリーズ

Ambari on Docker

 Apache AmbariでHadoopクラスタをDocker上にセットアップしてみます。AmbariはHadoop管理プラットフォームです。ブラウザの管理画面からHadoopのプロビジョニングや監視を行うことができますが、今回はAmbari ShellのCLIからHDPをクラスタをセットアップしてみます。

 SequenceIQが公開しているsequenceiq/ambariのDockerイメージをpullします。リポジトリはdocker-ambariです。

$ docker pull sequenceiq/ambari

 docker-ambariをダウンロードしてシェルスクリプトを読み込みます。

$ git clone https://github.com/sequenceiq/docker-ambari
$ cd docker-ambari
$ source ambari-functions

 ambari-functionsにはamb-*関数が定義されています。Ambari on Dockerのセットアップ前に環境変数を確認してみます。

$ amb-settings
  NODE_PREFIX=amb
  CLUSTER_SIZE=3
  AMBARI_SERVER_NAME=amb-server
  IMAGE=sequenceiq/ambari:2.1.2-v1
  DOCKER_OPTS=
  AMBARI_SERVER_IP=
  CONSUL=amb-consul
  CONSUL_IMAGE=sequenceiq/consul:v0.5.0-v6
  DRY_RUN=false

 Dockerに4ノードのクラスタを構築します。4ノードのうち1ノードはAmbari Serverになります。そのためHadoopクラスタは3ノードのコンテナで構成されます。

$ amb-start-cluster 4

コンテナが起動するとAMBARI_SERVER_IP環境変数にAmbari ServerコンテナのIPアドレスが設定されます。

$ amb-settings
  NODE_PREFIX=amb
  CLUSTER_SIZE=3
  AMBARI_SERVER_NAME=amb-server
  IMAGE=sequenceiq/ambari:2.1.2-v1
  DOCKER_OPTS=
  AMBARI_SERVER_IP=172.17.0.3
  CONSUL=amb-consul
  CONSUL_IMAGE=sequenceiq/consul:v0.5.0-v6
  DRY_RUN=false

 AmbariのREST APIをcurlコマンドからAmbariが管理しているホストの情報を確認してみます。

$ curl -u admin:admin  http://$AMBARI_SERVER_IP:8080/api/v1/hosts
{
  "href" : "http://172.17.0.3:8080/api/v1/hosts",
  "items" : [
    {
      "href" : "http://172.17.0.3:8080/api/v1/hosts/amb1.service.consul",
      "Hosts" : {
        "host_name" : "amb1.service.consul"
      }
    },
    {
      "href" : "http://172.17.0.3:8080/api/v1/hosts/amb2.service.consul",
      "Hosts" : {
        "host_name" : "amb2.service.consul"
      }
    },
    {
      "href" : "http://172.17.0.3:8080/api/v1/hosts/amb3.service.consul",
      "Hosts" : {
        "host_name" : "amb3.service.consul"
      }
    }
  ]
}

 別のシェルから実行するなどAMBARI_SERVER_IP環境変数が読み込まれていない場合は手動で設定します。

$ AMBARI_SERVER_IP=$(docker inspect --format="{{ .NetworkSettings.IPAddress }}" amb-server)

Ambari Shell

Ambari Shellにもsequenceiq/ambari-shellDockerイメージが公開されています。リポジトリはdocker-ambari-shellです。今回はsequenceiq/ambariに入っているambari-shell.shからAmbari Shellを起動します。

$ docker run -it --rm \
  --link amb-server:ambariserver \
  --entrypoint /bin/sh \
  sequenceiq/ambari \
  ./ambari-shell.sh

 Ambari Shellが起動しました。

AMBARI_HOST=172.17.0.3
[DEBUG] waits for ambari server: 172.17.0.3 RUNNING ...

[DEBUG] waits until 1 hosts connected to server ...
[DEBUG] connected hosts: 3
    _                _                   _  ____   _            _  _
   / \    _ __ ___  | |__    __ _  _ __ (_)/ ___| | |__    ___ | || |
  / _ \  | '_ ` _ \ | '_ \  / _` || '__|| |\___ \ | '_ \  / _ \| || |
 / ___ \ | | | | | || |_) || (_| || |   | | ___) || | | ||  __/| || |
/_/   \_\|_| |_| |_||_.__/  \__,_||_|   |_||____/ |_| |_| \___||_||_|

Welcome to Ambari Shell. For command and param completion press TAB, for assistance type 'hint'.
ambari-shell>

Blueprint

BlueprintはHadoopクラスタをJSON形式で定義します。Web画面のウィザードを使わなくてもREST APIやAmbari Shellからクラスタのプロビジョニングを行うことができます。

CloudbreakのBlueprint

 SequenceIQCloudbreakBlueprintsにいくつかBlueprintの例が掲載されています。CloudbreakはAmbariをベースにしたクラウド向けのHadoop管理ツールです。Azure、AWS、GCP、OpenStackのクラウドとDockerにも対応しています。ドキュメントを読むとAmbari Blueprintだけでも使えそうです。

datascientistをセットアップ

 Cloudbreakのリポジトリからdatascientist.bpから、Dockerコンテナで構成したAmbariノードにHDPクラスタをプロビジョニングします。

 デフォルトで登録されているsingle-node-hdfs-yarnを適用したプロビジョニングの流れは次のようになります。

blueprint defaults
blueprint list
cluster build --blueprint single-node-hdfs-yarn
cluster autoAssign
cluster create
tasks

 先ほど起動したAmbari Shellの中でdatascientistのBlueprintのURLを登録します。

ambari-shell> blueprint add --url https://raw.githubusercontent.com/sequenceiq/cloudbreak/master/core/src/main/resources/defaults/blueprints/datascientist.bp
Blueprint: 'datascientist' has been added

 登録したdatascientistをビルドします。Ambariホストの情報とBlueprintにて疑義されたホストグループが表示されます。

ambari-shell> cluster build --blueprint datascientist
  HOSTNAME             STATE
  -------------------  -------------------
  amb3.service.consul  amb3.service.consul
  amb1.service.consul  amb1.service.consul
  amb2.service.consul  amb2.service.consul

  HOSTGROUP  COMPONENT
  ---------  ----------------------
  client     TEZ_CLIENT
  client     YARN_CLIENT
  client     HIVE_CLIENT
  client     HDFS_CLIENT
  client     PIG
  client     MAPREDUCE2_CLIENT
  client     ZOOKEEPER_CLIENT
  client     HCAT
  client     METRICS_COLLECTOR
  client     SPARK_CLIENT
  client     METRICS_MONITOR
  client     HBASE_CLIENT
  slave_1    HBASE_REGIONSERVER
  slave_1    NODEMANAGER
  slave_1    DATANODE
  slave_1    METRICS_MONITOR
  master_1   RESOURCEMANAGER
  master_1   JOURNALNODE
  master_1   WEBHCAT_SERVER
  master_1   MYSQL_SERVER
  master_1   ZOOKEEPER_CLIENT
  master_1   HISTORYSERVER
  master_1   SECONDARY_NAMENODE
  master_1   METRICS_MONITOR
  master_1   NAMENODE
  master_1   ZEPPELIN_MASTER
  master_1   TEZ_CLIENT
  master_1   YARN_CLIENT
  master_1   MAPREDUCE2_CLIENT
  master_1   HDFS_CLIENT
  master_1   HIVE_SERVER
  master_1   HBASE_MASTER
  master_1   PIG
  master_1   SPARK_JOBHISTORYSERVER
  master_1   HIVE_METASTORE
  master_1   ZOOKEEPER_SERVER
  master_1   APP_TIMELINE_SERVER

 cluster autoAssignを実行するとホストグループの定義に応じて自動的にAmbariホストがアサインされます。今回は3つのホストグループに1つずつ手動でホストをアサインしていきます。

CLUSTER_BUILD:datascientist> cluster assign --hostGroup master_1 --host amb1.service.consul
amb1.service.consul has been added to master_1
CLUSTER_BUILD:datascientist> cluster assign --hostGroup slave_1 --host amb2.service.consul
amb2.service.consul has been added to slave_1
CLUSTER_BUILD:datascientist> cluster assign --hostGroup client --host amb3.service.consul
amb3.service.consul has been added to client

 最後にcluster createコマンドを実行してHDPクラスタのプロビジョニングを開始します。

CLUSTER_BUILD:datascientist> cluster create --exitOnFinish true

 tasksコマンドを実行すると各コンポーネントのインストール状況がわかります。またシェルの右上に完了までの全体のパーセントが表示されます。IDCFクラウドのstandard.L16 (4 CPU x 2.4 GHz 16 GB RAM)の仮想マシンでは13分ほどかかりました。

ConsulとNginxのリバースプロキシ

 HadoopクラスタのサービスディスカバリにはConsulを使っています。Dockerイメージはsequenceiq/consul、リポジトリはgliderlabs/docker-consulからforkしたsequenceiq/docker-consulです。

psコマンドでコンテナのポートを確認します。

$ docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                                                              NAMES
ce146ebf73f1        sequenceiq/ambari:2.1.2-v1    "/start-agent"           12 minutes ago      Up 12 minutes       8080/tcp                                                           amb3
9c23d449cb83        sequenceiq/ambari:2.1.2-v1    "/start-agent"           12 minutes ago      Up 12 minutes       8080/tcp                                                           amb2
162662822eb1        sequenceiq/ambari:2.1.2-v1    "/start-agent"           12 minutes ago      Up 12 minutes       8080/tcp                                                           amb1
6729936f59f8        sequenceiq/ambari:2.1.2-v1    "/start-server"          12 minutes ago      Up 12 minutes       8080/tcp                                                           amb-server
02ee7f29a74e        sequenceiq/consul:v0.5.0-v6   "/bin/start -server -"   12 minutes ago      Up 12 minutes       53/tcp, 53/udp, 8300-8302/tcp, 8400/tcp, 8500/tcp, 8301-8302/udp   amb-consul

 上記のようにDockerコンテナのポートはDockerホストにマップしていません。そのためDockerホストからしかDockerコンテナのIPアドレスへアクセスができません。今回の環境はIDCFクラウド上の仮想マシンなので、パブリックIPアドレスからAmbariとZeppelinの管理画面にアクセスできるようにNignxコンテナでリバースプロキシを作ります。

Consul

 Ambari ServerのREST APIのJSONを見やすくするためにjqをDockerホストにインストールします。

$ wget -P /usr/local/bin jq http://stedolan.github.io/jq/download/linux64/jq
$ chmod u+x /usr/local/bin/jq
$ which jq
/usr/local/bin/jq

Consulクラスタのノードを表示してみます。

$ AMB_CONSUL=$(docker inspect --format="{{ .NetworkSettings.IPAddress }}" amb-consul)
$ echo $AMB_CONSUL
172.17.0.2
$ curl -s $AMB_CONSUL:8500/v1/catalog/nodes | jq .
[
  {
    "Node": "amb-consul.service.consul",
    "Address": "172.17.0.2"
  },
  {
    "Node": "amb-server",
    "Address": "172.17.0.3"
  },
  {
    "Node": "amb1",
    "Address": "172.17.0.4"
  },
  {
    "Node": "amb2",
    "Address": "172.17.0.5"
  },
  {
    "Node": "amb3",
    "Address": "172.17.0.6"
  },
  {
    "Node": "ambari-8080",
    "Address": "172.17.0.3"
  }
]

 Consulに登録されたサービスを表示します。

$ curl -s $AMB_CONSUL:8500/v1/catalog/services | jq .
{
  "amb-server": [],
  "amb1": [],
  "amb2": [],
  "amb3": [],
  "ambari-8080": [],
  "consul": []
}

 amb-consulサービスの詳細を表示します。

$ curl -s $AMB_CONSUL:8500/v1/catalog/service/consul | jq .
[
  {
    "Node": "amb-consul.service.consul",
    "Address": "172.17.0.2",
    "ServiceID": "consul",
    "ServiceName": "consul",
    "ServiceTags": [],
    "ServiceAddress": "",
    "ServicePort": 8300
  }
]

 digコマンドでConsulのDNSサービスを見ることもできます

$ dig @$AMB_CONSUL -p 53 amb-consul.service.consul

; <<>> DiG 9.9.5-9+deb8u3-Debian <<>> @172.17.0.2 -p 53 amb-consul.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 65241
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;amb-consul.service.consul.     IN      A

;; Query time: 1 msec
;; SERVER: 172.17.0.2#53(172.17.0.2)
;; WHEN: Sat Dec 05 21:47:03 JST 2015
;; MSG SIZE  rcvd: 43

Consul TempateとNginx

 Consul Templateを使いDockerコンテナの情報からNginxの設定ファイルを生成します。jlordiales/nginx-consulのDockerイメージが公開されています。今回はAmbari用にリポジトリをforkしました。

以下のようなDockerfileからDockerイメージをビルドします。

FROM nginx:latest

ENV CONSUL_TEMPLATE_VERSION 0.11.0
ENV CONSUL_URL consul:8500

ADD start.sh /bin/start.sh
RUN rm -v /etc/nginx/conf.d/*.conf

ADD https://github.com/hashicorp/consul-template/releases/download/v${CONSUL_TEMPLATE_VERSION}/consul_template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.zip /tmp/consul-template.zip

RUN apt-get update && apt-get install unzip -y && \
    unzip -j -d /usr/local/bin /tmp/consul-template.zip

EXPOSE 8080 9995 9996
VOLUME /templates

CMD ["/bin/start.sh"]
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Consul Templateのテンプレートはservice.ctmplです。9995と9996はZeppelinサーバーが起動しているamb1ノードにプロキシーします。9996ポートはWebSocket用にヘッダーも追加します。8080ポートはAmb Serverコンテナが起動しているamb-serverノードにプロキシーします。

server {
  listen 9995;

  location / {
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-Host $host;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_pass         http://{{with node "amb1"}}{{.Node.Address}}{{end}}:9995;
  }
}

server {
  listen 9996;

  location / {
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-Host $host;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_pass         http://{{with node "amb1"}}{{.Node.Address}}{{end}}:9996;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_read_timeout 86400;
  }
}

server {
  listen 8080;

  location / {
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-Host $host;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_pass         http://{{with node "amb-server"}}{{.Node.Address}}{{end}}:8080;
  }
}

 forkしたリポジトリをcloneしてDockerイメージをビルドします。

$ git clone https://github.com/masato/docker-nginx-consul.git
$ cd docker-nginx-consul
$ docker build -t nginx-consul .

 --dns--dns-searchフラグをつけてNginxのコンテナを起動します。--dnsフラグの順番はDockerホスト、Google DNSの前にConsulコンテナのIPアドレスを指定するとNginxコンテナの/etc/resolv.confは以下のようになります。

/etc/resolv.conf
search service.consul
nameserver 172.17.0.2
nameserver 172.17.0.1
nameserver 8.8.8.8

 Ambari Serverの管理画面で使う8080、ZeppelinのNotebookに使う9995と9996ポートをDockerホストにマップして外部から接続できるようにします。

$ AMB_CONSUL=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" amb-consul)
$ echo $AMB_CONSUL
172.17.0.2
$ docker run \
  --name nginx \
  -d \
  -p 8080:8080 -p 9995:9995 -p 9996:9996 \
  --volume $PWD/service.ctmpl:/templates/service.ctmpl \
  --dns $AMB_CONSUL \
  --dns 172.17.0.1 \
  --dns 8.8.8.8 \
  --dns-search service.consul \
  nginx-consul

 Nginxコンテナに入り名前解決ができるようになったか確認します。

$ docker exec -it nginx bash
$ echo $CONSUL_URL
consul:8500
$ ping -c 1 amb1
PING amb1.service.consul (172.17.0.4): 56 data bytes
64 bytes from 172.17.0.4: icmp_seq=0 ttl=64 time=0.049 ms
--- amb1.service.consul ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.049/0.049/0.049/0.000 ms

 

 最後にpsコマンドで今回作成したDockerコンテナを確認します。

$ docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                                                                       NAMES
48df8cfdd49f        nginx-consul                  "/bin/start.sh"          29 minutes ago      Up 29 minutes       80/tcp, 0.0.0.0:8080->8080/tcp, 443/tcp, 0.0.0.0:9995-9996->9995-9996/tcp   nginx
ce146ebf73f1        sequenceiq/ambari:2.1.2-v1    "/start-agent"           2 hours ago         Up 2 hours          8080/tcp                                                                    amb3
9c23d449cb83        sequenceiq/ambari:2.1.2-v1    "/start-agent"           2 hours ago         Up 2 hours          8080/tcp                                                                    amb2
162662822eb1        sequenceiq/ambari:2.1.2-v1    "/start-agent"           2 hours ago         Up 2 hours          8080/tcp                                                                    amb1
6729936f59f8        sequenceiq/ambari:2.1.2-v1    "/start-server"          2 hours ago         Up 2 hours          8080/tcp                                                                    amb-server
02ee7f29a74e        sequenceiq/consul:v0.5.0-v6   "/bin/start -server -"   2 hours ago         Up 2 hours          53/tcp, 53/udp, 8300-8302/tcp, 8400/tcp, 8301-8302/udp, 8500/tcp            amb-consul

HDFS

 Zeppelinの実行をする前にHDFSにrootユーザーのディレクトリを作成します。hdfsユーザーにスイッチして/user/rootディレクトリを作成します。

$ docker exec -it amb1 bash
$ hadoop fs -ls /user
Found 4 items
drwxrwx---   - ambari-qa hdfs          0 2015-12-05 12:08 /user/ambari-qa
drwxr-xr-x   - hcat      hdfs          0 2015-12-05 12:09 /user/hcat
drwx------   - hive      hdfs          0 2015-12-05 12:09 /user/hive
drwxrwxr-x   - spark     hdfs          0 2015-12-05 12:08 /user/spark
$ su hdfs 
$ hadoop fs -mkdir /user/root
$ hadoop fs -chown root /user/root

コンポーネントの再起動

 理由はよくわかりませんがmaster_1グループのコンポーネントを再起動しないとZeppelinの実行に失敗してしまうようです。

 Ambariの管理画面をパブリックIPアドレスからブラウザで開きます。

ambari-server.png

Hostsメニューからamb1.service.consulを開いてRestart All Componentsを実行します。

ambari-restart.png

 コンポーネントの再起動が終了するとようやくZeppelinが使えるようになります。9995ポートをブラウザで開きます。

zeppelin-9995.png

参考

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8