すずけんメモ

技術メモです

Vagrant環境にpuppetを利用してさくっとelasticsearchのclusterを作成する

cluster構成をつくってみる。結論から言うと、

  • ちゃんとnetwork.hostVMに設定する
  • すると勝手にmulticastでnodeが発見される

以下の記事と同様にelasticsearch用のノードをもう1つ作る。

NodeのディスカバリにはZen Discoveryを利用する。単純にマルチキャストを利用すればよいだろう。と思ったらエラー。どうやらnetwork.hostをちゃんと設定しなければならないらしい。

結論、というか設定

以下のように設定する。

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "centos64"
  config.vm.box_url = "http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210.box"

  config.vm.define :search01 do |search_config|
      search_config.vm.hostname = "search01.local"
      search_config.vm.network "private_network", ip: "192.168.10.114"
  end

  config.vm.define :search02 do |search_config|
      search_config.vm.hostname = "search02.local"
      search_config.vm.network "private_network", ip: "192.168.10.115"
  end

manifests/search.pp

include search

ついでにelasticsearch-headとMarvel, elastic-HQもいれてある。

roles/search/manifests/init.pp

class search {
  service { 'iptables':
    enable => false,
    ensure => stopped,
  }

  class { 'elasticsearch':
    package_url => 'https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.11.noarch.rpm',
    java_install => true,
    config => {
      'cluster' => {
        'name' => 'test-es-cluster01'
      },
      'network.host' => '_eth1:ipv4_',
      'marvel.agent.exporter.es.hosts' => ['192.168.10.114:9200','192.168.10.115:9200']
    }
  }

  elasticsearch::plugin{'elasticsearch/marvel/latest':
    module_dir => 'marvel'
  }

  elasticsearch::plugin{'mobz/elasticsearch-head':
    module_dir => 'head'
  }

  elasticsearch::plugin{'royrusso/elasticsearch-HQ':
    module_dir => 'HQ'
  }
}

あとは

$ vagrant up search01
$ vagrant up search02
$ vagrant ssh-config search01 --host search01.local >> ~/.ssh/config
$ vagrant ssh-config search02 --host search02.local >> ~/.ssh/config
$ ssh search01.local "cd /vagrant && sudo puppet module install elasticsearch-elasticsearch"
$ ssh search02.local "cd /vagrant && sudo puppet module install elasticsearch-elasticsearch"
$ ssh search01.local "cd /vagrant && sudo puppet apply --modulepath=/etc/puppet/modules:modules:roles manifests/search.pp"
$ ssh search02.local "cd /vagrant && sudo puppet apply --modulepath=/etc/puppet/modules:modules:roles manifests/search.pp"

とすればVMが2つ立ち上がってelasticsearchのクラスタが組まれる。Marvelでみるとこんな感じ。

f:id:suzu_v:20140205232227p:plain

ついでにもう1つノード足すとこんな感じになる。設定は割愛。単純に同じようにVMつくってmanifestあてれば勝手にclusterに追加される。簡単。

f:id:suzu_v:20140205232320p:plain

中身的なこと

ちなみに各サーバの/etc/elasticsearch/elasticsearch.ymlは以下のようになる。Marvelはデフォルトだとlocalhost:9200をみるようになっているので、明示してあげるようにしている。

### MANAGED BY PUPPET ###
---
cluster:
  name: test-es-cluster01
marvel:
  agent:
    exporter:
      es:
        hosts:
             - 192.168.10.114:9200
             - 192.168.10.115:9200
network:
  host: _eth1:ipv4_

ここ、明示しなくても勝手にノード検出するんじゃないかという気がしているけど、とりあえずこれで。

http://www.elasticsearch.org/guide/en/marvel/current/#stats-export をみると以下のように載っている。

A list of hosts in hostname:port format to which statistics and events will be sent. Data will be sent to the first host, but will failover to the next host(s) if the first is not reachable. Defaults to ["localhost:9200"].

ということなので、複数載せておけば勝手にfailoverして隣のホストにexportするようにしてくれるらしい。便利。

細かいエラーの話

環境によるかもしれないけど、VMで立ち上げたnodeはデフォルトでnetwork.hosteth0を見るようになっている。この場合、例えばunicastでpingしてnodeを検出しようとしてもerrorがでてしまう。この場合、network.host10.0.2.15になっている。

[2014-02-05 07:30:18,350][INFO ][discovery.zen            ] [Rocket Raccoon] failed to send join request to master [[Kismet][QjUBU_iKTc6oLJn-trkEVw][inet[/10.0.2.15:9300]]], reason [org.elasticsearch.transport.RemoteTransportException: [Rocket Raccoon][i
net[/10.0.2.15:9300]][discovery/zen/join]; org.elasticsearch.ElasticSearchIllegalStateException: Node [[Rocket Raccoon][oWubpeP8Q5atLeAIlD2rWA][inet[/10.0.2.15:9300]]] not master for join request from [[Rocket Raccoon][oWubpeP8Q5atLeAIlD2rWA][inet[/10.0.
2.15:9300]]]]

network.hostVMのhostにしてもやっぱりだめ。

[2014-02-05 07:34:24,593][WARN ][discovery.zen            ] [Americop] failed to connect to master [[Kismet][QjUBU_iKTc6oLJn-trkEVw][inet[/10.0.2.15:9300]]], retrying...
org.elasticsearch.transport.ConnectTransportException: [Kismet][inet[/10.0.2.15:9300]] connect_timeout[30s]
        at org.elasticsearch.transport.netty.NettyTransport.connectToChannels(NettyTransport.java:718)
        at org.elasticsearch.transport.netty.NettyTransport.connectToNode(NettyTransport.java:647)
        at org.elasticsearch.transport.netty.NettyTransport.connectToNode(NettyTransport.java:615)
        at org.elasticsearch.transport.TransportService.connectToNode(TransportService.java:129)
        at org.elasticsearch.discovery.zen.ZenDiscovery.innerJoinCluster(ZenDiscovery.java:335)
        at org.elasticsearch.discovery.zen.ZenDiscovery.access$500(ZenDiscovery.java:76)
        at org.elasticsearch.discovery.zen.ZenDiscovery$1.run(ZenDiscovery.java:283)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Caused by: java.net.ConnectException: Connection refused: /10.0.2.15:9300
        at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
        at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:739)
        at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.connect(NioClientBoss.java:150)
        at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.processSelectedKeys(NioClientBoss.java:105)
        at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.process(NioClientBoss.java:79)
        at org.elasticsearch.common.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:318)
        at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.run(NioClientBoss.java:42)
        at org.elasticsearch.common.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
        at org.elasticsearch.common.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
        ... 3 more

host側ネットワークを見れるようにするためにnetwork.hostを変更すればよかったのでした。 @johtani さんのreplyで気が付きました。ありがとうございました。