はじめに
ElasticsearchのクラスタをGCPで構築する際に使った方が良いプラグインを紹介したいと思います。
それは、GCE discovery pluginです。
このプラグインを使用することで、Unicastでホスト名やIPアドレスを指定することなく、よしなにクラスタを組んでくれます。
以前にEC2 discovery pluginの紹介をしましたが、インスタンスがダウンした際にノードIDの重複問題を抱えてました。
そこの改善も含めて今回記載させて頂きます。
それでは早速ですが、構築していきます( ゚Д゚)ゞビシッ
Setup Firewall Rules
ファイアウォールルールを作成します。
ノード間で通信するために9200-9300でポートを解放します。
また、9200でHTTP通信を受け付けるため解放します。
$ gcloud compute firewall-rules create elasticsearch --direction=INGRESS \
--priority=1000 --network=default --action=ALLOW \
--rules=tcp:9200,tcp:9300-9400 --source-ranges=0.0.0.0/0
Create an instance using gcloud SDK
インスタンスを構築する準備ができましたので、インスタンスを構築します。
gcloudが実行できる環境を前提に進めます。
もし、gcloudの実行環境がない場合は、Cloud SDKインストールのサイトを参考にしてください。
$ gcloud compute instances create es-gce-discovery \
--machine-type=n1-standard-2 --subnet=default \
--min-cpu-platform=Automatic \
--tags=elasticsearch,http-server,https-server \
--image=ubuntu-1604-xenial-v20180306 \
--image-project=ubuntu-os-cloud \
--boot-disk-size=10GB --boot-disk-type=pd-standard \
--boot-disk-device-name=sgce-discovery --scopes=compute-ro
インスタンスが立ち上がったのでSSHで接続します。
gcloud compute ssh es-gce-discovery
Install Java
インスタンスにJDK 8をインストールします。
$ sudo apt-get update
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java8-installer
$ sudo apt-get install oracle-java8-set-default
$ java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
Install Elasticsearch and GCE discovery plugin
Elasticsearchをインストールするため、PGP-keyをインストールします。
Install Elasticsearch with Dibian Packages
$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
次に"apt-transport-https"をインストールします。
$ sudo apt-get install apt-transport-https
リポジトリを追加します。
$ echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list
Elasticsearchをインストールします。
$ sudo apt-get update && sudo apt-get install elasticsearch
$ sudo /usr/share/elasticsearch/bin/elasticsearch -version
Version: 6.2.4, Build: ccec39f/2018-04-12T20:37:28.497551Z, JVM: 1.8.0_171
次に"GCE discovery plugin"をインストールします。
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install discovery-gce
インストールが完了したので、Elasticsearchの設定ファイルに設定を追加します。
$ sudo vim /etc/elasticsearch/elasticsearch.yml
### クラスタ名はデフォルト"elasticsearch"
cluster.name: lannister
### ノード名を動的に設定するため、${HOSTNAME} を使用する
node.name: ${HOSTNAME}
### GCEのホスト名をネットワークサービスにバインド
network.host: _gce:hostname_
### スプリットブレインを避けるため、適正なノード数にする
discovery.zen.minimum_master_nodes: 2
### "GCE discovery plugin"の設定をする
cloud.gce.project_id: "your Project-Name"
cloud.gce.zone: us-east1-b
discovery.zen.hosts_provider: gce
Elasticsearchを起動します。
$ sudo /etc/init.d/elasticsearch start
curlコマンドでサービス起動の確認をします。
$ curl ${HOSTNAME}:9200
起動確認できたので、インスタンスからログオフします。
ちなみにですが、Elasticsearch起動後にログを確認すると永遠と"WARN"が出力されますが、無視してください。
1台しかないから当たり前ですが、ノード数が足りないために発生しています。
$ sudo tail -f /var/log/elasticsearch/lannister.log
[2018-05-13T07:45:11,358][WARN ][o.e.d.z.ZenDiscovery ] [es-gce-discovery] not enough master nodes discovered during pinging (found [[Candidate{node={es-gce-discovery}{SAFhkm66S7eGgURWMHS3Ww}{EHnLunWFQTuYHgVJ-WXDkA}{es-gce-discovery.c.winter-jet-194500.internal}{10.142.0.2:9300}, clusterStateVersion=-1}]], but needed [2]), pinging again
Create a GCE custom image
ローカル環境からディスクイメージを保管するバケットを作成します。
$ gsutil mb -p "your Project-Name" -c regional -l us-east1 gs://es-test-bucket/
Elasticsearchをインストールしたインスタンスを停止します。
$ gcloud compute instances stop es-gce-discovery
停止したインスタンスのスナップショットを取得します。
$ gcloud compute disks snapshot es-gce-discovery \
--snapshot-names=es-gce-discovery-snapshot
取得したスナップショットで、GCEディスクを作成します。
$ gcloud compute disks create es-gce-discovery-disk \
--source-snapshot es-gce-discovery-snapshot
元のイメージディスクより50%より大きい一時ディスクを作成します。
今回は、元のディスクが10GBなため、一時ディスクは15GBで作成します。
$ gcloud compute disks create es-gce-discovery-temp-disk --size 15GB
スコープのstorage-rwを使用し、二つのディスクをマウントした一時的なインスタンスを作成します。
$ gcloud compute instances create es-temp-instance --scopes storage-rw \
--disk name=es-gce-discovery-disk,device-name=es-gce-discovery-disk \
--disk name=es-gce-discovery-temp-disk,device-name=es-gce-discovery-temp-disk
作成できたら一時インスタンスにアクセスします。
$ gcloud compute ssh sherry-temp-instance
ディスクを確認します。
$ ls /dev/disk/by-id/
google-es-gce-discovery-disk google-persistent-disk-0 scsi-0Google_PersistentDisk_es-gce-discovery-disk-part1 scsi-0Google_PersistentDisk_persistent-disk-0-part1
google-es-gce-discovery-disk-part1 google-persistent-disk-0-part1 scsi-0Google_PersistentDisk_es-gce-discovery-temp-disk
google-es-gce-discovery-temp-disk scsi-0Google_PersistentDisk_es-gce-discovery-disk scsi-0Google_PersistentDisk_persistent-disk-0
次にディスクフォーマットし、マウントします。
$ sudo mkdir /mnt/tmp
$ sudo mkfs.ext4 -F /dev/disk/by-id/google-es-gce-discovery-temp-disk
$ sudo mount -o discard,defaults /dev/disk/by-id/google-es-gce-discovery-temp-disk /mnt/tmp
イメージをマウントします。
$ sudo mkdir /mnt/image-disk
$ sudo mount /dev/disk/by-id/google-es-gce-discovery-disk-part1 /mnt/image-disk
Elasticsearchのデータディレクトリを削除します。
Elasticsearchが初めて開始すると新しいインスタンス毎にElasticsearchのデータディレクトリが作成されます。
$ sudo rm -fR /mnt/image-disk/var/lib/elasticsearch/nodes
SSHキーを削除します。
$ sudo rm -f /mnt/image-disk/home/micci184/.ssh/authorized_keys
イメージをアンマウントします。
$ sudo umount /mnt/image-disk/
一時ディスク上のイメージディスクからdisk.rawを作成します。
disk.rawという名前である必要があります。
$ sudo dd if=/dev/disk/by-id/google-es-gce-discovery-disk of=/mnt/tmp/disk.raw bs=4096
disk.rawファイルのtarファイルを作成します。
$ cd /mnt/tmp
$ sudo tar czvf es-gce-discovery-disk.tar.gz disk.raw
バケットにtarファイルをコピーします。
$ gsutil cp /mnt/tmp/es-gce-discovery-disk.tar.gz gs://es-test-bucket/
ファイル転送が完了したら、一時インスタンスをログオフします。
最後に新しいインスタンスを作成するためのカスタムイメージを作成します。
$ gcloud compute images create es-gce-discovery-image \
--source-uri=https://storage.googleapis.com/es-test-bucket/es-gce-discovery-disk.tar.gz
Create instances based on our custom image
3つの新しいインスタンスを作成します。
$ gcloud compute instances create es-instance-1 \
--machine-type=n1-standard-2 --subnet=default \
--min-cpu-platform=Automatic --tags=elasticsearch,http-server,https-server \
--image=es-gce-discovery-image --image-project=winter-jet-194500 \
--boot-disk-size=20GB --boot-disk-type=pd-standard \
--boot-disk-device-name=es-instance-1 --scopes=compute-ro
$ gcloud compute instances create es-instance-2 \
--machine-type=n1-standard-2 --subnet=default \
--min-cpu-platform=Automatic --tags=elasticsearch,http-server,https-server \
--image=es-gce-discovery-image --image-project=winter-jet-194500 \
--boot-disk-size=20GB --boot-disk-type=pd-standard \
--boot-disk-device-name=es-instance-2 --scopes=compute-ro
$ gcloud compute instances create es-instance-3 \
--machine-type=n1-standard-2 --subnet=default \
--min-cpu-platform=Automatic --tags=elasticsearch,http-server,https-server \
--image=es-gce-discovery-image --image-project=winter-jet-194500 \
--boot-disk-size=20GB --boot-disk-type=pd-standard \
--boot-disk-device-name=es-instance-3 --scopes=compute-ro
3台のインスタンスが作成できたら、Elasticsearchのサービスを起動します。
自動起動させたい場合は、Elasticsearchの公式サイトを参考にして設定してください。
$ gcloud compute ssh es-instance-1
$ sudo /etc/init.d/elasticsearch start
$ exit
$ gcloud compute ssh es-instance-2
$ sudo /etc/init.d/elasticsearch start
$ exit
$ gcloud compute ssh es-instance-3
$ sudo /etc/init.d/elasticsearch start
$ exit
es-instance-1インスタンスから、curlコマンドでクラスタの確認をします。
クラスタ内の3つのノードが表示されれば完了です。
$ curl es-instance-1:9200/_cat/nodes
10.142.0.4 12 30 4 0.09 0.14 0.08 mdi - es-instance-1
10.142.0.5 14 30 8 0.31 0.28 0.13 mdi * es-instance-2
10.142.0.6 15 30 8 0.34 0.29 0.13 mdi - es-instance-3
いかがでしたか?
GCP環境でもElasticsearchクラスタの環境を柔軟に構築できることがわかったかと思います。
ありがとうございました!
参考
Getting Started with the GCE Discovery Plugin on Google Cloud
Install Elasticsearch with Debian Package
Cloud SDKのインストール