WSL2 + DockerでElasticsearchクラスタを気軽に試したい

## はじめに
本記事は[Elasticsearchアドベントカレンダー(2020年)](https://qiita.com/advent-calendar/2020/elasticsearch)の13日目の記事です。
たまたま空いてたので小ネタ投稿させていただきます。

## この記事の内容
Elasticsearchを触っていると、バージョンアップに伴って新機能がリリースされて、ちょっと試しておきたいな、と思うことがあります。

以前は律義にオンプレ仮想環境やクラウドにVMをあげて、SSHしてコマンド実行しながらセットアップをしていました。特に３台以上のクラスタ環境を作る際には、ホスト名設定、SSH鍵作成・配布、yum repoファイル作成、yum install、Elasticsearch設定ファイル編集、サービス起動、などなど手間がかかっていました。

最近Windows10上でWSL2が使えるようになり、WSL2上のUbuntu18.04にdockerを入れて、全く同じ構成を作るようにして非常にお手軽にクラスタセットアップまでできるようになりましたので、やり方を共有いたします。なお、そんなことしなくてもelastic社が配布するdockerイメージでいいじゃないか、という方もいらっしゃるかと思いますが、本格利用する際にはこの仮想マシンベースの構成で設計、設定をすることをふまえて、同じ手順(ベースOSにyum/apt installして設定ファイルをカスタマイズする方式)をとっています。

あくまで個人のやり方であり、これがbest practiceでもないですし、もしもっと便利な方法を普段利用されている方がいたらぜひ教えてください。また、WSL2はそのバージョンや環境により、permission系のエラーが出たりすることもよくありますので、Linuxホスト上のdocker環境の方が問題なく動くかもしれない点、ご了承ください。

## 前提
基本的にdockerが使える環境であれば本稿の手順はなぞれると思います。自分はWindows10のWSL2上にUbuntu18.10を入れています。

## 手順
以下の順序で作業を行います。
なお、スクリプト類はgithubでも公開しています。(https://github.com/tetsuyasodo/esdocker)

1. Dockerfileを使ってベースOSイメージに起動時実行スクリプトを埋め込む
2. 上記イメージを使ってdocker runする（３台分）
3. 動作確認

### 1. Dockerfileを使ってイメージ作成
ベースOSはCentOS7:latestを使います。１点だけ、OS起動後にスクリプトを実行したいので、rc.localにファイルをADDしておきます。

カスタムスクリプトは以下のようなもので、yum installでelasticsearchとkibanaをインストールし、設定ファイルを修正してクラスタ構成がとれるようにしています。
（ノード名がハードコードされていますが、このあたり汎用化の余地はありますね。）

```bash
#!/bin/bash

cat <<'EOF' >/etc/yum.repos.d/es.repo
[elasticsearch-7.x]
name=Elasticsearch repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF

yum install -y elasticsearch kibana

cat <<'EOF' >>/etc/elasticsearch/elasticsearch.yml
cluster.name: cluster01
network.host: 0.0.0.0
discovery.seed_hosts: ["es01","es02","es03"]
cluster.initial_master_nodes:  ["es01","es02","es03"]
EOF

cat <<'EOF' >>/etc/kibana/kibana.yml
server.host: "0.0.0.0"
EOF

systemctl daemon-reload
systemctl start elasticsearch
systemctl start kibana
```

これを埋め込んだDockerイメージを作りたいので、以下のようなDockerfileを作ります。

```
FROM centos:centos7
COPY essetup.sh /etc/rc.local
RUN chmod 755 /etc/rc.local
```

これら２ファイルを同じディレクトリ作成するようにしてください。

```bash
$ ls
Dockerfile  essetup.sh
```

そのままdocker buildでイメージを作成します。これは３台共通となります。

```bash
$ docker build -t escluster .
```

### 2. Dockerイメージの起動（３台分）
次に、docker runで３台分イメージを起動します。-pオプションでdockerホスト側からポートフォワードを設定できますが、es01の9200と5601はおそらく必要ですが、残りはなくても動作はしますので設定は任意でOKです。

```bash
$ docker run -it -d --network elasticstack -p 9200:9200 -p 5601:5601 --hostname es01 --name es01 --privileged escluster /sbin/init
$ docker run -it -d --network elasticstack -p 9201:9200 -p 5602:5601 --hostname es02 --name es02 --privileged escluster /sbin/init
$ docker run -it -d --network elasticstack -p 9202:9200 -p 5603:5601 --hostname es03 --name es03 --privileged escluster /sbin/init
```

この方法は、Dockerイメージは「素の」CentOSのままで、OS起動後に都度yum installをしていますので、インストールに少し時間がかかります。4-5分Coffee Timeをとって、しばらくしてから、systemctlコマンドでelasticsearchやkibanaが入っているかを確認してみるといいでしょう。

```bash
$ docker exec -it es01 systemctl status kibana
```

または、bashで直接コンテナに入ってみるという方法もあります。

```bash
$ docker exec -it es01 /bin/bash
# tail /var/log/yum.log
# ps -ef
```

### 3.動作確認
しばらく待つと3ノードとも起動し、自動的にクラスタを形成します。curlコマンドあるいはkibanaからクラスタへアクセスが可能です。

```bash
$ curl localhost:9200/_cat/nodes
```

Kibanaの場合は、ブラウザから"http://localhost:5601"でアクセス可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51832/ac139f5f-a207-78a4-d7f7-8814cc2002ef.png)

## 環境の削除
最後不要になったコンテナはstop/rmで削除できます。

```bash
$ docker stop es0{1,2,3}
$ docker rm es0{1,2,3}
$ docker rmi escluster  ### イメージも削除する場合に実行
```


## まとめ
手元のdocker環境で手軽にElasticsearchクラスタを起動、試す方法について紹介しました。
この方法であれば、頻度の早いElasticsearchの新バージョンの機能確認が簡単に行えるので、よろしければご活用ください。