docker-compose を使って Elasticsearch のクラスタ環境を構築した時のメモ

タイトルの通りでございます。

構築の仕方は先人の方々がネットにまとめてくださっているのですが、自身の環境だと全くそのままの進め方だとうまくいかない部分とかがあったので、自分なりに試した結果をまとめます。
構築に使用した YAML 類は下記 [GitHub](https://github.com/naotawool/elasticsearch-cluster-and-kibana-using-docker-compose) に上げております。

## 個別の VirtualBox を立てる

何も考えずに `docker-compose.yml` 書いて実行すると `default` という VM が立ち上がってしまいます。
別に `default` を使っていなければ何も問題ないですが、私は別件で `default` の VM を既に利用済であるため、これが使われるのは若干困る。

なので、今回検証用の VM を作成します。
名前は `es-default` で（もう少しセンスのある名前でも OK）。

```bash
$ docker-machine create --driver virtualbox es-default
```

作成したら起動。

```bash
$ docker-machine start es-default
```

で、ここが重要。
Docker Machine が起動したら仮想メモリの数を増やしておく。
これをやらないと Elasticsearch が Docker 上で起動できないので。

```bash
$ docker-machine ssh es-default "cat /proc/sys/vm/max_map_count"
65530
$ docker-machine ssh es-default "sudo sysctl -w vm.max_map_count=262144"
vm.max_map_count = 262144
$ docker-machine ssh es-default "cat /proc/sys/vm/max_map_count"
262144
```

## Elasticsearch 起動

VM の準備ができたら `docker-compose.yml` を用意して、実際に Elasticsearch を起動していきます。
最終的に出来上がった YAML は（改善の余地はまだまだあると思いますが）こんな感じです。

```yaml
version: '2.2'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.5.0
    container_name: elasticsearch
    environment:
      - node.name=es01
      - discovery.zen.ping.unicast.hosts=elasticsearch2
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - ./elasticsearch/data:/usr/share/elasticsearch/data
      - ./elasticsearch/logs:/var/log/elasticsearch
      - ./elasticsearch/config/elasticsearch-cluster.yml:/usr/share/elasticsearch/config/elasticsearch.yml
    ports:
      - 9200:9200
      - 9300:9300
    networks:
      - esnet
  elasticsearch2:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.5.0
    container_name: elasticsearch2
    environment:
      - node.name=es02
      - discovery.zen.ping.unicast.hosts=elasticsearch
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - ./elasticsearch/data:/usr/share/elasticsearch/data
      - ./elasticsearch/logs:/var/log/elasticsearch
      - ./elasticsearch/config/elasticsearch-cluster.yml:/usr/share/elasticsearch/config/elasticsearch.yml
    networks:
      - esnet

networks:
  esnet:
```


上記 YAML を使い、下記コマンドを実行してクラスタ構成にした Elasticsearch を起動していきます。

```bash
$ docker-compose up -d
Creating network "elasticsearchclusterandkibanausingdockercompose_esnet" with the default driver
Creating elasticsearch  ... done
Creating elasticsearch2 ... done
```

もしここで下記エラーが表示された場合 env コマンドで表示される一番下の `eval` コマンドを叩いておく。

```bash
ERROR: Windows named pipe error: 指定されたファイルが見つかりません。 (code: 2)
```

```bash
$ docker-machine env es-default
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="C:\Users\user\.docker\machine\machines\es-default"
export DOCKER_MACHINE_NAME="es-default"
export COMPOSE_CONVERT_WINDOWS_PATHS="true"
# Run this command to configure your shell:
# eval $("{Docker Path}docker-machine.exe" env es-default)
```

私のマシンスペックだと起動に少々時間がかかったため、ログを見ながら起動したかどうかを確認しました。

```bash
$ docker-compose logs -f
```

起動したら ps コマンドでステータスを確認しておきます。
無事に起動したらクラスタ状態を確認します。

```bash
# IP アドレスを確認しておく
$ docker-machine ip es-default
192.168.99.100

$ curl http://192.168.99.100:9200/_cluster/health?pretty
{
  "cluster_name" : "docker-cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 2,
  "number_of_data_nodes" : 2,
  "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
}
```

無事ステータスも green で起動できているようです。

あとはインデックス追加したりドキュメント追加したりといったことを行いますが、クラスタ構成の起動としては達成できたので今日はここまで。

検証が終わったらきちんと立てた Docker やら VM を落とすのを忘れずに。

```bash
$ docker-compose down
$ docker-machine stop es-default
```

## 参考資料

これらを達成するためにいろいろなまとめを参考にしました。
先人の皆さま、ありがとうございます！

[Running a 3 Node Elasticsearch Cluster With Docker Compose on Your Laptop for Testing](
https://blog.ruanbekker.com/blog/2018/04/29/running-a-3-node-elasticsearch-cluster-with-docker-compose-on-your-laptop-for-testing/)
[ElasticsearchとKibanaをDockerでサクッとインストールする(シングルノード・マルチノード)](https://qiita.com/romiogaku/items/ad82180cf2cbc280c10e)
[Elasticsearch Cluster and Kibana using docker-compose](https://medium.com/@maxy_ermayank/elasticsearch-cluster-and-kibana-using-docker-compose-4f9c4d6c5470)
[Elasticsearchのインストール及び設定　その４　Config(yml)の修正及びElasticsearchの起動](https://gitya107.hatenablog.com/entry/2018/05/13/161656)
[Install Elasticsearch with Dockeredit](https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html)
[Docker(compose)初学者が困ったときに役立つコマンド集](https://qiita.com/ryurock/items/d1372e9b4d561343a308)
[Elasticsearch導入前に気を付けておきたいこと！](https://qiita.com/uzresk/items/e0b10c14875b79c450f2)
[メモリ制限下でElasticsearch5のDockerコンテナを立ち上げる](https://qiita.com/suhirotaka/items/789e28c2a8880e3b6fce)