2019年6月14日金曜日

Ubuntu16.04 上に ElasticSearch7.1 クラスタを構築してみた

概要

ElasticSearch の 7.1 で 3 台構成のクラスタを組んでみました
Vagrant で 3 台の Ubuntu を構築しそれぞれで ElasticSearch のプロセスを 1 つずつ起動してクラスタを組んでみます
今回は Vagrant を使いましたが EC2 や GCE などのクラウドリソースでも問題ないです

環境

  • Ubuntu 16.04 LTS
  • Vagrant 2.1.1
  • ElasticSearch 7.1.1

Vagrantfile

3 台作成します
メモリは 1024 にしていますが余裕があればもっと高い値を設定してください
box ファイルは ubuntu/xenial64 を使用しています
ホスト間で通信できるようにインタフェースを一つ追加してます

Vagrant.configure("2") do |config|
  config.vm.define "vm01" do |v|
    v.vm.box = "ubuntu/xenial64"
    v.vm.network "private_network", ip: "192.168.99.200"
    v.vm.provider "virtualbox" do |vb|
      vb.memory = "1024"
    end
  end
  config.vm.define "vm02" do |v|
    v.vm.box = "ubuntu/xenial64"
    v.vm.network "private_network", ip: "192.168.99.201"
    v.vm.provider "virtualbox" do |vb|
      vb.memory = "1024"
    end
  end
  config.vm.define "vm03" do |v|
    v.vm.box = "ubuntu/xenial64"
    v.vm.network "private_network", ip: "192.168.99.202"
    v.vm.provider "virtualbox" do |vb|
      vb.memory = "1024"
    end
  end
end
  • vagrant up

VM 設定

それぞれに ssh して作業します

  • vagrant ssh vm01
  • vagrant ssh vm02
  • vagrant ssh vm03

Vagrant ユーザで作業する上でカーネルパラメータなどのチューニングが必要なので行います

  • sudo vim /etc/security/limits.conf
vagrant hard nproc 4096
vagrant soft nproc 4096
vagrant hard nofile 65535
vagrant soft nofile 65535

各ホストをホスト名でアクセスできるように hosts ファイルに記載します

  • sudo vim /etc/hosts
192.168.99.200 vm01
192.168.99.201 vm02
192.168.99.201 vm02

あとはホスト名を設定しましょう
ここで設定したホスト名は ElasticSearch のクラスタを構成する際に使われるノード名 (node.name) でそのまま使用します

  • sudo hostnamectl set-hostname vm01
  • sudo hostnamectl set-hostname vm02
  • sudo hostnamectl set-hostname vm02

最後に再起動しましょう

  • sudo reboot -h now

elasticsearch インストール

各ホストで行います
tar.gz ファイルをダウンロードして解凍するだけで OK です

  • curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.1.1-linux-x86_64.tar.gz
  • tar -xvf elasticsearch-7.1.1-linux-x86_64.tar.gz

elasticsearch 起動 (vm01, vm02)

まずは 2 台構成のクラスタを構築します
どちらも同じコマンドを実行するのでそれぞれに ssh して実行しましょう
直前に sysctl を実行していますが「VM 設定」のところで /etc/sysctl.conf に記載しても OK です

  • cd elasticsearch-7.1.1/
  • sudo sysctl -w vm.max_map_count=262144
  • ES_JAVA_OPTS="-Xms512m -Xmx512m" ./bin/elasticsearch -d -p $(hostname).pid -Ecluster.name=my_cluster -Ediscovery.seed_hosts=vm01,vm02 -Ecluster.initial_master_nodes=vm01,vm02 -Enetwork.host=_enp0s9_

いろいろとパラメータを指定しています
-d はデーモンとして実行、-p は pid ファイルを生成します

クラスタを構築する上で大事なのは -E 付きのオプションです
まず cluster.name=my_cluster はクラスタ名を指定します
好きな名前を付けて OK です
他のホストで起動するときも同じクラスタ名を指定することで同一クラスタに所属されることができます
discovery.seed_hosts=vm01,vm02 はクラスタに所属させるホストを指定します
cluster.initial_master_nodes=vm01,vm02 はクラスタ構築時にマスターノードになれるホストを指定します
network.host=_enp0s9_ はホスト間でやり取りするネットワークを指定します
enp0s9 はインタフェースを指定しており 192.168.99 帯の固定 IP が振られたインタフェースを指定しています
また今回は node.name を指定していません
指定しなかった場合は ElasticSearch が自動的にホスト名を引っ張ってノード名に設定するので今回は指定しませんでした

しばらくすると 9200 と 9300 が 192.168.99 の IP で LISTEN します
2 台のホストで LISTEN したらクラスタが構築されているか確認しましょう

クラスタの状態確認

API を叩きて確認します
vm01, vm02 どちらのホストでも問題ないので API をコールしてみましょう

$curl $(hostname):9200/_cat/health
1560334522 10:15:22 my_cluster green 2 2 0 0 0 0 0 0 - 100.0%
$ curl $(hostname):9200/_cat/nodes
192.168.99.200 37 94 14 0.30 0.21 0.08 mdi - vm01
192.168.99.201 25 93 14 0.31 0.26 0.14 mdi * vm02

ノードが 2 台ありかつステータスが green になっていれば問題なくクラスタが構築されています
なお今回は vm02 が初期状態では master に選ばれました

ホスト追加 (vm03)

では vm03 も追加してみます
先程の vm01, vm02 と同じように elasticsearch のプロセスを起動すれば OK です

  • cd elasticsearch-7.1.1/
  • sudo sysctl -w vm.max_map_count=262144
  • ES_JAVA_OPTS="-Xms512m -Xmx512m" ./bin/elasticsearch -d -p $(hostname).pid -Ecluster.name=my_cluster -Ediscovery.seed_hosts=vm01,vm02,vm03 -Ecluster.initial_master_nodes=vm01,vm02,vm03 -Enetwork.host=_enp0s9_

discovery.seed_hostscluster.initial_master_nodes に vm03 が追加されています
あとは同じです
9200 と 9300 が LISTEN したら同じようにクラスタの状態を API で確認しましょう
3 台になっていることが確認できれば OK です
なおホストを追加しても master は変わりませんでした

$ curl $(hostname):9200/_cat/health
1560337529 11:05:29 my_cluster green 3 3 0 0 0 0 0 0 - 100.0%
$ curl $(hostname):9200/_cat/nodes
192.168.99.202 33 93 0 0.08 0.12 0.05 mdi - vm03
192.168.99.200 19 92 0 0.07 0.03 0.01 mdi - vm01
192.168.99.201 36 93 0 0.00 0.00 0.00 mdi * vm02

failover 確認 (vm02)

最後に failover を確認しましょう
master であった vm02 のプロセスを kill してみます

  • kill -SIGTERM $(cat vm02.pid)

すると別のホストが master に昇格しステータスが green に戻ります
今回の場合は特にデータやアクセスもないので確認が難しいですが failover 中はステータスが red or yellow になり瞬間的にクラスタが使えない状態になるようです

$ curl $(hostname):9200/_cat/health
1560338344 11:19:04 my_cluster green 2 2 0 0 0 0 0 0 - 100.0%
$ curl $(hostname):9200/_cat/nodes
192.168.99.202 26 93 0 0.00 0.00 0.00 mdi - vm03
192.168.99.200 38 92 1 0.00 0.02 0.00 mdi * vm01

再度 vm02 の elasticsearch を起動しましょう
vm02 を再度起動する場合はなぜか discovery.seed_hostscluster.initial_master_nodes に vm03 を追加しないでも大丈夫でした (もしかしたら追加したほうがいいかも)

  • ES_JAVA_OPTS="-Xms512m -Xmx512m" ./bin/elasticsearch -d -p $(hostname).pid -Ecluster.name=my_cluster -Ediscovery.seed_hosts=vm01,vm02 -Ecluster.initial_master_nodes=vm01,vm02 -Enetwork.host=_enp0s9_

これで vm02 が再度クラスタに加わりました

$ curl $(hostname):9200/_cat/health
1560338437 11:20:37 my_cluster green 3 3 0 0 0 0 0 0 - 100.0%
$ curl $(hostname):9200/_cat/nodes
192.168.99.200 24 92 0 0.00 0.01 0.00 mdi * vm01
192.168.99.202 38 93 0 0.00 0.00 0.00 mdi - vm03
192.168.99.201 25 94 0 0.23 0.10 0.03 mdi - vm02

ハマったポイント

Vagrant の場合デフォルトのホスト名が ubuntu-xenial になっています
これで node.name を指定してやっていたのですがうまくできなかったので hostname を設定して行いました
また、discovery.seed_hostscluster.initial_master_nodes を IP で指定していたのですがうまくいかなかったのでホスト名を指定するようにしました
ホスト名にした場合ホスト間の通信はホスト名で引ける必要があるので /etc/hosts に記載しています

また基本はトライアンドエラーを何度も行ったのですが data/ に前の間違ったクラスタ情報があると何度やっても失敗したので次にトライする場合はフォルダごと削除するようにしましょう

最後に

ElasticSearch 7.1 でクラスタ構成を組んでみました
VM で作業したのでカーネルパラメータなどのチューニングも必要になります
基本は起動する際のパラメータを駆使してクラスタを構成することができますがパラメータではなく config/elasticsearch.yml に記載しても効果は同じなのでパラメータが嫌いな方は設定ファイルに記載しても OK です

また今回、ホストはすべて node.master=true で行いました
ノードの種類もいろいろあるらしいので興味があれば見てください
よくよく調べると今回のやり方は Bootstrap Cluster というやり方のようです
docker でクラスタを構成場合も同じ方法を使っていました

参考サイト

0 件のコメント:

コメントを投稿