Elasticsearchを最小構成でクラスタリングしてみる

# やりたいこと

- Elasticsearchを最小構成(3台)でクラスタリングする
- 奇数台なのは偶数台の場合、スプリットブレインシンドロームを引き起こす可能性があるため

# 検証環境

- VagrantでホスティングしたUbuntu Server 22.04 LTS x 3台

# インストール

- 基本的に[公式ドキュメント](https://www.elastic.co/guide/en/elasticsearch/reference/current/deb.html)の手順に従っている
- 3台それぞれのマシンで行う

```bash
$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
$ sudo apt update
$ sudo apt install apt-transport-https -y
$ echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
$ sudo apt update
$ sudo apt install elasticsearch -y
```

# Elasticsearchの設定

- ※ 変更点のみ抜粋
- クラスタ名やノード名を設定
- リモートからHTTP(TCPポート9200番)でのアクセスを受け付けるよう設定
- クラスタに所属するノード一覧を設定
- マスターノードとして選出可能なノード一覧を設定
- 認証やHTTPS通信をオフにするよう設定(検証を簡単にするため)
- ※ 注意点として、 `network.host` を `0.0.0.0` にすると、ネットワークインタフェースが複数ある場合に意図しないIPアドレスがバインドされ、ノード間の通信が正常に行えなくなることがある

 ## ノード1の設定

```bash
$ sudo vim /etc/elasticsearch/elasticsearch.yml
cluster.name: my-es-cluster
node.name: node-1
network.host: 192.168.56.10
http.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["192.168.56.10:9300", "192.168.56.11:9300", "192.168.56.12:9300"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
xpack.security.enabled: false
```

## ノード2の設定

```bash
$ sudo vim /etc/elasticsearch/elasticsearch.yml
cluster.name: my-es-cluster
node.name: node-2
network.host: 192.168.56.11
http.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["192.168.56.10:9300", "192.168.56.11:9300", "192.168.56.12:9300"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
xpack.security.enabled: false
```

## ノード3の設定

```bash
$ sudo vim /etc/elasticsearch/elasticsearch.yml
cluster.name: my-es-cluster
node.name: node-3
network.host: 192.168.56.12
http.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["192.168.56.10:9300", "192.168.56.11:9300", "192.168.56.12:9300"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
xpack.security.enabled: false
```

# UFWの設定

- UFWを有効化する設定
- クライアントからのHTTPでのアクセスに使用するTCPポート9200番への外部からのアクセスを許可する設定
- ノード間の通信に使用するTCPポート9300番への外部からのアクセスを許可する設定
- 3台それぞれのマシンで行う

```bash
$ sudo ufw status
Status: inactive

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

$ sudo ufw status
Status: active

$ sudo ufw allow 9200/tcp
Rule added
Rule added (v6)

$ sudo ufw allow 9300/tcp
Rule added
Rule added (v6)

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
9200/tcp                   ALLOW       Anywhere                  
9300/tcp                   ALLOW       Anywhere                  
9200/tcp (v6)              ALLOW       Anywhere (v6)             
9300/tcp (v6)              ALLOW       Anywhere (v6)
```

# 起動する

- 3台それぞれのマシンで行う

```bash
$ sudo systemctl start elasticsearch

$ sudo systemctl status elasticsearch
● elasticsearch.service - Elasticsearch
     Loaded: loaded (/lib/systemd/system/elasticsearch.service; disabled; vendor preset: enabled)
     Active: active (running) since Mon 2023-12-11 07:47:16 UTC; 20min ago
       Docs: https://www.elastic.co
   Main PID: 1587 (java)
      Tasks: 69 (limit: 2237)
     Memory: 1.5G
        CPU: 5min 18.107s
     CGroup: /system.slice/elasticsearch.service
             ├─1587 /usr/share/elasticsearch/jdk/bin/java -Xms4m -Xmx64m -XX:+UseSerialGC -Dcli.name=>
             ├─1645 /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.netwo>
             └─1665 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller

Dec 11 07:45:47 ubuntu2204.localdomain systemd[1]: Starting Elasticsearch...
Dec 11 07:46:03 ubuntu2204.localdomain systemd-entrypoint[1587]: Dec 11, 2023 7:46:03 AM sun.util.loc>
Dec 11 07:46:03 ubuntu2204.localdomain systemd-entrypoint[1587]: WARNING: COMPAT locale provider will>
Dec 11 07:47:16 ubuntu2204.localdomain systemd[1]: Started Elasticsearch.

$ ss -nlp | grep 9200
tcp   LISTEN 0      4096                                            *:9200                   *:*

$ ss -nlp | grep 9300
tcp   LISTEN 0      4096                                            *:9300                   *:*
```

# 動作確認

```bash
# クラスタ内の各ノードの情報を取得
# node-1に「*」がついており、マスターノードであることを表している
$ curl -X GET "192.168.56.10:9200/_cat/nodes"
192.168.56.10 32 96  1 0.06 0.12 0.07 cdfhilmrstw * node-1
192.168.56.11 28 95  1 0.08 0.15 0.08 cdfhilmrstw - node-2
192.168.56.12 25 80 14 1.47 0.83 0.32 cdfhilmrstw - node-3

# node-1のヘルスチェック
$ curl -X GET "192.168.56.10:9200/_cluster/health?pretty" 
{
  "cluster_name" : "my-es-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
}

# node-2のヘルスチェック
$ curl -X GET "192.168.56.11:9200/_cluster/health?pretty"
{
  "cluster_name" : "my-es-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
}

# node-3のヘルスチェック
$ curl -X GET "192.168.56.12:9200/_cluster/health?pretty"
{
  "cluster_name" : "my-es-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
}
```