notebook

都内でWEB系エンジニアやってます。

# ansibleでelasticsearch + kibana4

ansibleでelasticsearch + kibana4

経緯

  • ログのvisualizeしたいよね
  • kibana使ってみよう!4が出てるみたいだ!

という感じでやることになったのですが、クラスタ構成での検証とか何かと作っては壊してっていう作業が行えたほうが便利そうなのでansibleでぱぱっと作れるようにしました。

ログの入れ込みは別途fluentd,embulkを使って入れ込むことになるのですが、環境作るだけなら一発でできるようになりました。

なお、クラスタ構成の可視化のためにelasticsearch-headを導入しました

elasticsearch-head

構成

ansible-elasticsearch-kibana4

hostsに書いてあるとおりですが...

  • elasticsearchのmasterノード
    • 192.168.20.18
  • elasticsearchのdataノード
    • 192.168.20.19
    • 192.168.20.20
    • 192.168.20.21
  • kibana用サーバ
    • 192.168.20.18

て構成で1台がelasticsearchのmasterノード兼kibana用のサーバという形になります

やったこと

elasticsearchのインストール

elasticsearchのインストールはjavaのインストール、rpmのインストールだけで終わるのでOK

クラスター構成にするための設定

  • /etc/elasticsearch/elasticsearch.yml

vagrant環境の場合は下記設定する必要があるよう

network.host: '_eth1:ipv4_'

その他デフォルトだとクラスター構成にするための設定はコメントアウトされているので適切な設定にしつつコメントアウトを外します

  • masterノード
cluster.name: elasticserach-master
node.master: true
node.data: false
  • dataノード
cluster.name: elasticserach-data
node.master: false
node.data: true

ansibleで実行すれば必要ないけど実際にサーバでコマンド打つなら下記

/etc/init.d/elasticsearch start

これだけでOK,なんて簡単!!

クラスタ構成についてはmasterノードが先に立ち上がらないとうまくいかないよう

  • elasticsearch-head
http://192.168.20.18:9200/_plugin/head/

上記にアクセスすればクラスタの状況などがWEBで把握できるようになります

f:id:swfz:20150407224345p:plain

kibanaのインストール

  • 設定ファイル(/path/to/kibana/config/kibana.yml)

設定ファイルはelasticsearchの問い合わせ先をmasterノードのIPにするだけ

http://192.168.20.18:9200

普通に起動するなら/path/to/kibana/bin/kibanaで起動できるようになります

これで起動は完了!ポートは5601番で起動してるので該当IPの5601番にブラウザでアクセスすればkibanaの画面が表示されるかと思います

f:id:swfz:20150407224201p:plain

supervisorのインストールと設定

  • supervisorのインストール

supervisorのバージョンは2系と3系がある模様、yumで入れられるのは2系、3系はeasy_installを使うよう

documentには/etc/supervisor.d/のディレクトリを作成して*.iniを置けば監視対象のプログラムを追加できる、と書いてあったんだけど、どうもうまくいかない。。。

3系ならできるかと思ったけど、3系でもうまくいかなかったのでとりあえずはyumから入れる2系で書きました

epelリポジトリが必要なのでインストールも忘れずに

ansible上だとroles/supervisor/meta/main.ymlに依存情報を追加して終わり

ansibleにはsupervisorctlっていうコマンドもあってそれを使ってsupervisorの設定に変更があった場合はreloadさせようとしたけど、実行まではするもののansible実行側で終了判定ができずにコマンドが終了しないという感じになってしまっていた

commandでリロードしてしまえば一応OKっぽかったので一旦その方向にした、使える!と思っただけに少し残念

また、supervisor系の設定に関してはほぼ参考にしたサイトのをほぼコピペなので考慮の余地あるかも

最後にsupervisorをupstartに登録してsupervisor自体が落ちるのを監視するようにしました

ここは未チェックw

ansible

今回ansibleで書いてみて便利だなと思ったのは

  • ファイル、ディレクトリの存在確認

statコマンドでファイルの情報を取得、registerで変数に登録しそこから色々できるよう

# ファイルの存在確認
stat: /path/to/kibana/bin/kibana
register: binfile

when: binfile.stat.md5 is not defined
get_url: --------


# ディレクトリの存在確認
stat: /usr/share/elasticsearch/plugins/head
register: plugin_head

when: plugin_head.stat.exists == false
command: /usr/share/elasticsearch/bin/plugin --install mobz/elasticsearch-head
  • hostsのIPを変数として使う
# site.yml
    - { role: kibana4, kibana_elasticsearch_ip: "{{  groups.elasticsearch_master.0  }}" }

groupsで各サーバの変数を取ってこれるようです

今回はmasterノードのIPをkibanaのconfigに設定する必要があったのでkibanaのroleにelasticsearchのmasterノードのIPを渡すようにしています

他にも方法はありそうだったのでご指摘あったら教えていただきたいです!

  • iniファイルで色々

ini形式の設定ファイルならini_fileモジュールを使うことができます

なので置換とかしなくてOK

programの箇所をキーとしてwith_dictモジュールで実現したかったけどちょっと要件と合わなかったようでうまくいかず普通にwith_itemsでやりました。

いくらかは見やすくなったのかな

# roles/kibana4/vars/main.yml
supervisor_config:
  - { program: "{{ kibana_supervisor_program_name }}", option: command, value: "{{ src }}/{{ version }}/bin/kibana"}
  - { program: "{{ kibana_supervisor_program_name }}", option: autostart, value: true }
  - { program: "{{ kibana_supervisor_program_name }}", option: autorestart, value: true }
  - { program: "{{ kibana_supervisor_program_name }}", option: log_stdout, value: true }
  - { program: "{{ kibana_supervisor_program_name }}", option: log_stderr, value: true }
  - { program: "{{ kibana_supervisor_program_name }}", option: stopsignal, value: QUIT }
  - { program: "{{ kibana_supervisor_program_name }}", option: logfile, value: "/var/log/supervisor/{{ kibana_supervisor_program_name }}.log" }

# roles/kibana4/tasks/main.yml
  ini_file: dest=/etc/supervisord.conf
            section=program:{{ item.program }}
            option={{ item.option }}
            value={{ item.value }}
  with_items: supervisor_config
  • handler notify
# roles/supervisor/hendler/main.yml
- name: reload supervisor
  command: supervisorctl reload

# roles/kibana4/tasks/main.yml
- name: set kibana config
  replace: dest={{ src }}/{{ version }}/config/kibana.yml regexp='http://.*:9200' replace="http://{{ kibana_elasticsearch_ip }}:9200" backup=yes
  notify: reload supervisor

mysqlでいうトリガーのようなもの

そのタスク実行時のステータスがchangedの時のみnotifyで指定されたnameのタスクを行う

roleだとroles/supervisor/handler/main.ymlのようにhandlerのディレクトリ以下に配置する

主に設定変更したら再起動しますとかそういう感じの使い方をするイメージですね

まとめ

ansibleで書いてみたけどやっぱり便利、sandboxと併用すれば作って壊しが簡単にできる

ディレクトリ構成とか書き方とか色々見たものの何が良いかよくわからなかったのでアドバイスとかいただけたら幸いです

kibanaの使い方とか、elasticsearchのクラスタ構成についてはまた今度