vagrant+ansibleでelasticsearchのクラスタを作ってみる

# vagrant+ansibleでelasticsearchのクラスタを作ってみる

構築するのは ``centos6``の上。
[前に書いた記事](http://qiita.com/arc279/items/616faf10a84f7da3a6b8)と構成なんかはほぼ同じ。

```
.
├── Vagrantfile
├── ansible.cfg
├── elasticsearch-1.3.4.zip
├── es.yml
├── inventory
├── ssh.config
└── templates
    └── elasticsearch.yml
```

_elasticsearch-1.3.4.zip_ は[公式](http://www.elasticsearch.org/overview/elkdownloads/)から落としてきたやつ。

## vmの設定

box登録したりとかの細かい説明は[前回](http://qiita.com/arc279/items/616faf10a84f7da3a6b8)書いたので、そっちを参照されたい。

```rb:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  config.vm.define :node1 do |node|
    node.vm.box = "centos6"
    node.vm.hostname = "node1"
    node.vm.network :private_network, ip: "192.168.33.10"

    node.vm.provider :virtualbox do |vb|
      vb.customize ["modifyvm", :id, "--memory", "512"]
    end
  end

  config.vm.define :node2 do |node|
    node.vm.box = "centos6"
    node.vm.hostname = "node2"
    node.vm.network :private_network, ip: "192.168.33.11"

    node.vm.provider :virtualbox do |vb|
      vb.customize ["modifyvm", :id, "--memory", "512"]
    end
  end

end
```

```ini:inventory
[servers]
node1
node2
```

```text:ssh.config
Host node1
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/kuryu/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Host node2
  HostName 127.0.0.1
  User vagrant
  Port 2200
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/kuryu/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL
```

```ini:ansible.cfg
[defaults]
hostfile = inventory

[ssh_connection]
ssh_args = -F ssh.config
```

## playbook

* unarchiveモジュールにunzipが必要
* jdkも必要
* とりあえずesのheadプラグイン入れてみる

```yaml:es.yml
---
- hosts: servers
  user: vagrant

  vars:
    es_version: elasticsearch-1.3.4

  tasks:
  - yum: name={{item}} state=installed
    sudo: yes
    with_items:
    - libselinux-python
    - unzip
    - java-1.7.0-openjdk

  - unarchive: >
      src=./{{ es_version }}.zip
      # 何故かここだけ ~/ としてもローカルのhomeになってしまう
      dest=/home/vagrant/

  - template: >
      src=./templates/elasticsearch.yml
      dest=~/{{ es_version }}/config/

  - command: bin/plugin -install mobz/elasticsearch-head
    args:
      chdir: ~/{{ es_version }}
      creates: ~/{{ es_version }}/plugins/head
```

## elasticsearchの設定

とりあえず要点。

* `{{ inventory_hostname }}` で現在処理中のvmのnode名が取得できるので、esのnode名にそのまま使った。
* vagrantのprivate_networkだとnicがeth1になるので、`network.publish_host: _eth1:ipv4_`でそちらを見るように指定。
* `http.max_content_length`はPOSTでバルクインサートする時に、リクエストの`Content-Length`がこの値を超えると`TooLongFrameException`が出るので、大きめに設定しておく。

```text:templates/elasticsearch.yml
cluster.name: kuryu
node.name: {{ inventory_hostname }}

network.publish_host: _eth1:ipv4_

http.max_content_length: 500mb
```

## 起動

```bash
$ vagrant up
```

してから

```bash
$ ansible-playbook es.yml
```

これで、vmの _/home/vagrant/elasticsearch-1.3.4_ にelasticsearchが用意される。

で、それぞれ

```
$ vagrant ssh node1
```
```
$ vagrant ssh node2
```

でvmに入ってから、esを起動すると、

```
$ cd elasticsearch-1.3.4/
$ ./bin/elasticsearch
```

クラスタになってる。

```bash
$ curl 192.168.33.10:9200/_cat/nodes
node1 127.0.0.1 3 49 0.01 d * node1
node2 127.0.0.1 3 48 0.07 d m node2
```

同じネットワーク上の同じクラスタ名のインスタンスを見つけて自動でクラスタにしてくれるようだ。

とりあえず構築フェーズはこの辺で。

## 注意点

今回はvm上で組んだのでプライベートネットワーク内で済んだけど、
デフォルトの設定ファイル同士でもクラスタになってしまうようだ。

* 同じネットワーク内で、
* 他の人がデフォルトの状態で起動してたりすると、

知らないうちにクラスタになっちゃってて謎の挙動に悩まされたりするので、
__クラスタ名はちゃんと指定するとよいです__。