12
Help us understand the problem. What are the problem?

posted at

updated at

Dockerを使用した複数ホストでのElasticsearchクラスタの構築検証

※この記事は個人ブログに移行しました

Elasticsearchは公式でコンテナイメージを提供してくれているのでそれを利用してクラスタを組みたいと思います。
ドキュメントにはdocker-compose.ymlも公開されていますが、docker-composeということはコンテナホストはひとつになるから可用性的にNGだなー、と感じました。(Swarm modeとか使うと解決できるのかな?)
コンテナホストは複数台に分散したいと考えたので、検証してみました。

検証環境

  • Mac OS X El Capitan(10.11.6)
  • docker-machine version 0.10.0, build 76ed2a6
  • VirtualBox 5.1.14 r112924 (Qt5.6.2)

ポイント

  • docker-machineを利用してVirtualBox上に3つのコンテナホストを起動
  • 各コンテナホストに公式のコンテナイメージをデプロイ
  • Dockerのネットワークドライバはhostモードを利用する

検証手順

コンテナホストの準備

コンテナホストの作成

VirtualBox上にコンテナホストを3つ起動します。

$ docker-machine create --driver virtualbox elasticsearch1
$ docker-machine create --driver virtualbox elasticsearch2
$ docker-machine create --driver virtualbox elasticsearch3

コンテナホストのメモリマップ上限の引き上げ

公式にも書いてある通り、設定しないとコンテナが起動しない(開発者モードなら起動するかも)ので設定します。

$ docker-machine ssh elasticsearch1 sudo sysctl -w vm.max_map_count=262144
$ docker-machine ssh elasticsearch2 sudo sysctl -w vm.max_map_count=262144
$ docker-machine ssh elasticsearch3 sudo sysctl -w vm.max_map_count=262144

Elaticsearchの起動〜動作確認

Elasticsearchコンテナの起動

Elasticが独自に公開しているコンテナレジストリよりイメージを取得して起動します。
環境変数(-e)でパラメータを渡すとElasticsearchの設定を上書きできるのでいきなり起動できます。
検証で渡したパラメータは以下の通り。

環境変数名 パラメータに渡す値 説明
network.host _eth1:ipv4_ hostモードでコンテナを起動するとホストのNICが全部マッピングされますが、このオプションを指定しないとElasticsearchはeth0のIPアドレスをデフォルトで指定するようです。
eth0のIPアドレスはプライベートなIPアドレスが割り当てられていて外部と通信できないのでeth1を明示しています。
discovery.zen.ping.unicast.hosts 自分自身以外のコンテナホストのIPアドレスをカンマ区切り クラスタに参加させるホストを明示します。
discovery.zen.minimum_master_nodes 2 ノード数/2+1を設定するようドキュメントにも記載されているので従います。
xpack.security.enabled false 今回の検証には不要なのでX-PackのSecurityを無効化します。
xpack.monitoring.enabled false 今回の検証には不要なのでX-PackのMonitoringを無効化します。
xpack.watcher.enabled false 今回の検証には不要なのでX-PackのWatcherを無効化します。
xpack.graph.enabled false 今回の検証には不要なのでX-PackのGraphを無効化します。
xpack.ml.enabled false 今回の検証には不要なのでX-PackのMachine Learningを無効化します。
ES_JAVA_OPTS -Xms512m -Xmx512m Elasticsearchが使用するjavaのヒープサイズを指定します。
コンテナホストのメモリを増やすという方法もありますが、3台も2GB以上のホストを起動したらこのMacがゲロ重になるのでこうしました。

その他にコンテナに渡したオプションは以下の通り

オプション 説明
-d デタッチドモードでコンテナを起動。
説明はいらないですよね?
--network="host" コンテナのネットワークモードをhostに設定します。
コンテナホストのネットワークインターフェースがそのままコンテナ上でも利用されます。
-p 9200:9200 Elasticsearchのサービスポートを公開します。
-P(大文字)でもよかったかも。
-p 9300:9300 Elasticsearchがノード間のコミュニケーションで使用するポートを公開します。
-P(大文字)でもよかったかも。
1台目の起動
$ eval $(docker-machine env elasticsearch1)
$ docker run -d \
  -e "network.host=_eth1:ipv4_" \
  -e "discovery.zen.ping.unicast.hosts=$(docker-machine ip elasticsearch2),$(docker-machine ip elasticsearch3)" \
  -e "discovery.zen.minimum_master_nodes=2" \
  -e "xpack.security.enabled=false" \
  -e "xpack.monitoring.enabled=false" \
  -e "xpack.watcher.enabled=false" \
  -e "xpack.graph.enabled=false" \
  -e "xpack.ml.enabled=false" \
  -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
  --network="host" \
  -p 9200:9200 \
  -p 9300:9300 \
  docker.elastic.co/elasticsearch/elasticsearch:5.4.0
2台目の起動
$ eval $(docker-machine env elasticsearch2)
$ docker run -d \
  -e "network.host=_eth1:ipv4_" \
  -e "discovery.zen.ping.unicast.hosts=$(docker-machine ip elasticsearch1),$(docker-machine ip elasticsearch3)" \
  -e "discovery.zen.minimum_master_nodes=2" \
  -e "xpack.security.enabled=false" \
  -e "xpack.monitoring.enabled=false" \
  -e "xpack.watcher.enabled=false" \
  -e "xpack.graph.enabled=false" \
  -e "xpack.ml.enabled=false" \
  -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
  --network="host" \
  -p 9200:9200 \
  -p 9300:9300 \
  docker.elastic.co/elasticsearch/elasticsearch:5.4.0
3台目の起動
$ eval $(docker-machine env elasticsearch3)
$ docker run -d \
  -e "network.host=_eth1:ipv4_" \
  -e "discovery.zen.ping.unicast.hosts=$(docker-machine ip elasticsearch1),$(docker-machine ip elasticsearch2)" \
  -e "discovery.zen.minimum_master_nodes=2" \
  -e "xpack.security.enabled=false" \
  -e "xpack.monitoring.enabled=false" \
  -e "xpack.watcher.enabled=false" \
  -e "xpack.graph.enabled=false" \
  -e "xpack.ml.enabled=false" \
  -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
  --network="host" \
  -p 9200:9200 \
  -p 9300:9300 \
  docker.elastic.co/elasticsearch/elasticsearch:5.4.0

Clusterのステータスを確認する

3台起動したのでクラスタのステータスを確認してみます。

$ curl $(docker-machine ip elasticsearch1):9200/_cat/health?v
epoch      timestamp cluster        status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1496326996 14:23:16  docker-cluster green           3         3      0   0    0    0        0             0                  -                100.0%
$ curl $(docker-machine ip elasticsearch1):9200/_cluster/health?pretty
{
  "cluster_name" : "docker-cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 0,
  "active_shards" : 0,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

以下の点が確認できればよいと思います。

  • statusがgreen
  • ノードの数が3
  • データノードの数が3

インデックスを作って確認してみる

クラスタが組めてそうなのでインデックスを作ってみます。

$ curl -XPUT $(docker-machine ip elasticsearch1):9200/test?pretty
{
  "acknowledged" : true,
  "shards_acknowledged" : true
}

クラスタなので、どのIPアドレスに問い合わせても上記で作成したインデックスができていれば問題ないでしょう。
確認してみます。

1台目で確認
$ curl $(docker-machine ip elasticsearch1):9200/_cat/indices?v
health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   test  0iOZud02QHqPMkcDemgdWg   5   1          0            0      1.2kb           650b

1台目はできてます。ここはインデックスを作ったときに指定したホストなので当然ですね。

2台目で確認
$ curl $(docker-machine ip elasticsearch2):9200/_cat/indices?v
health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   test  0iOZud02QHqPMkcDemgdWg   5   1          0            0      1.2kb           650b

2台目でもできてますね。順調。

3台目で確認
$ curl $(docker-machine ip elasticsearch3):9200/_cat/indices?v
health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   test  0iOZud02QHqPMkcDemgdWg   5   1          0            0      1.2kb           650b

3台目にもありました。バッチリ。

まとめ

以上で複数ホストにまたがった可用性のあるElasticsearchクラスタをコンテナで起動することができました。
このあとはcloud-awsプラグインを使用してEC2上にデプロイする方法などを検証してみようかなーと思っています。(コンテナでもできるのかな?)
Amazon Elasticsearch ServiceはVPCに対応してないのが残念ですよね。 1

お気づきの点とかあれば優しくご指摘頂ければと思います。

  1. サポートしましたね

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
12
Help us understand the problem. What are the problem?