Specinfra Host InventoryのデータをFluentdで集めてElasticsearchに入れてKibanaで見る構成管理

# 前書き

@sawanoboly さんによる[Ohai版記事](http://qiita.com/sawanoboly/items/a8f9357f0f6044e7d7ff)のSpecinfra Host Inventory版的なやつです。
踏襲したタイトル付けたらメッチャ長いタイトルになったｗ

何気なく軽量で実行方式（ローカルとかSSH越しとか）が選べて取り回しの良いインベントリ収集ライブラリは何かに使えるんじゃないかなーと思いつつ、[Itamae](https://github.com/itamae-kitchen/itamae)はChef Server的な存在が居ないし、こういう感じでインベントリを集めてみるのはどうでしょうかというコンセプトモデル的な何かです。

# 構成
Azureの無料枠が余っていたのでAzure上でやってみましたが、
慣れてないので複数のVMを纏めて扱うのが厳しそうだったので、
普通に大きめのVMをWEBコンソールから立てて、その中にDockerで複数の環境を構築しました。
![es-specinfra1.png](https://qiita-image-store.s3.amazonaws.com/0/57327/f6e352e3-7b4f-6453-1b7b-8240137c270a.png)

# 詳細
## 構成方法
- [Chef](https://www.chef.io/)
- [test-kitchen](http://kitchen.ci/) + [kitchen-docker_cli](https://github.com/marcy-terui/kitchen-docker_cli)

`Chef`,`test-kitchen`は言わずもがなかと思いますが、`kitchen-docker_cli`は`kitchen-docker`への不満から生まれた[拙作](http://marcy.hatenablog.com/entry/2014/12/25/020211)のTest Kitchen Driverです。
SSHを排除するためにフルスクラッチで作っていて、Dockerネイティブな感じに使えるようにしており、`kitchen-docker`にあるオプションから主観で必要そうな部分を抑えた上で、NW周りのオプション等を強化したりしています。
詳しく知りたい方は[README](https://github.com/marcy-terui/kitchen-docker_cli)をお読みください。

`.kitchen.yml`はこんな感じです。

```yaml
---
driver:
  name: docker_cli

provisioner:
  name: chef_zero

platforms:
  - name: centos-6.6
  - name: fedora-20
  - name: ubuntu-14.04

suites:
  - name: elasticsearch
    driver_config:
      container_name: es
      publish: 5601:5601
      privileged: true
    excludes:
      - fedora-20
      - ubuntu-14.04
    run_list:
      - recipe[es-specinfra-example::elasticsearch]
  - name: fluentd01
    driver_config:
      link: es:es
    run_list:
      - recipe[es-specinfra-example::fluentd]
  - name: fluentd02
    driver_config:
      link: es:es
    run_list:
      - recipe[es-specinfra-example::fluentd]
```

実際に使用したCookbook等はこちらです。
https://github.com/marcy-cookbooks/es-specinfra-example

最近はTest-Kitchenが楽なのでカッチリやりたい時以外は大抵なんでもTest-Kitchenでやっちゃってます。

## Elasticsearch + Kibana
- [Elasticsearch](http://www.elasticsearch.org/overview/elasticsearch/) 1.4.4
- [Kibana](http://www.elasticsearch.org/overview/kibana/) 4

余談ですが、Kibana4はElasticsearch1.4.4以降でしか動かないですが、公式Cookbookが`attribute`で0.9とか古いバージョンで固定されててアレでした。
<ins>
2015/03/04追記：
`attribute`なので、自前Cookbook側で`1.4.4`に上書きするだけで、とりあえず動いています。
</ins>
`Elasticsearch`は公式Cookbookでサービス登録してくれるので、`Kibana`だけ`supervisord`で起動してます。
（`Kibana3`はjsのみでデーモンいらずでしたが、`Kibana4`はSinatraアプリで起動スクリプトが同梱されてます）
稀にESの受け入れ体制が整う前にKibanaが起動してしまうのか、リトライアウトしてconvergeに失敗するのですが、本当に稀なので今回はスルーｗ
<ins>
2015/03/05追記：
kibana`4.0.1`でESが起動していない場合にポーリングするよう修正されたそうなので、以降のバージョンであれば発生しないと思われます。
</ins>



## Fluentd
- [Fluentd](http://www.fluentd.org/) 0.12.6
- [fluent-plugin-forest](https://github.com/tagomoris/fluent-plugin-forest) 0.3.0
- [fluent-plugin-elasticsearch](https://github.com/uken/fluent-plugin-elasticsearch) 0.7.0
- [fluent-plugin-specinfra_inventory](https://github.com/marcy-terui/fluent-plugin-specinfra_inventory) 0.2.2

`fluent-plugin-specinfra_inventory`は今回[新しく作りました。](http://marcy.hatenablog.com/entry/2015/02/26/000842)
インベントリなんてそんなに頻繁に集めるものじゃないので、必ずしもFluentd Pluginじゃなくてよいという話もありますが、Outputが柔軟に変えられて良いというのと、[Ohaiの](https://github.com/frosenberg/fluent-plugin-ohai)もあるから良いかなとｗ

取得可能な全インベントリまたはインベントリを指定（複数可）して収集させます。
`Ohai`もそうですが、`Specinfra`もデータは全て`String`です。
このままだと不都合があるのでキャストするオプションも付けました。

設定ファイルはこんな感じです。

```
<source>
  type specinfra_inventory
  cast_num       true
  cast_byte      true
  cast_percent   true
  time_span 60
</source>
<match specinfra.inventory>
  type forest
  subtype elasticsearch
  <template>
    host es
    logstash_format true
    logstash_prefix fluentd-${hostname}
  </template>
</match>
```

このように、収集するインベントリのキーが指定されていない場合は、収集可能なインベントリの全てを収集します。
一部のみ取得したい場合は以下のように書きます。

```
<source>
  type specinfra_inventory
  inventory_keys ["platform", "hostname", "cpu.total"]
</source>
```

`"cpu.total"`のように`.`で区切るとネストされたHashの2階層目以降だけ取得することもできます。

# 動かしてみた
上記の`Fluentd`設定の`logstash_prefix`に準じたインデックスパターンを指定します。

![kibana1.png](https://qiita-image-store.s3.amazonaws.com/0/57327/c84ae22a-bd5e-7346-9518-fde80e5b8bd5.png)

収集できてますね。

![kibana2.png](https://qiita-image-store.s3.amazonaws.com/0/57327/6cbcc821-9043-88b6-4e40-8cf6cdb2c5a7.png)

例①　ホスト数の遷移　
![kibana4.PNG](https://qiita-image-store.s3.amazonaws.com/0/57327/837a5c30-e33b-8b2a-1099-9a664f1e19de.png)

例②　`platform`（≒ディストリ）の割合とそれに属するホスト

![kibana3.png](https://qiita-image-store.s3.amazonaws.com/0/57327/03cab301-8d2e-603e-d7b0-3690007c0011.png)

例③　ホストごとのCPUコア数（同一VM上にあるから全部同じｗ）
![kibana6.png](https://qiita-image-store.s3.amazonaws.com/0/57327/686c1604-c810-13e4-bf10-79e412f02c4a.png)
余談ですが、`--cpu-shares`とか`--memory-limit`とかのオプション付きで起動されたコンテナでコンテナ内から自身にかけられた制限の情報とかって知る方法無いんですかね？
使用できるメモリ容量から設定値を算出するCookbookとかあるので、取れると嬉しいのです。

または、これでやるのはどうなのかという話はありますが、監視っぽいこともできます。
例④　ホストごとの空きメモリの遷移（もっと色々あるけど、良い感じに線がバラけなかったｗ）

![kibana5.png](https://qiita-image-store.s3.amazonaws.com/0/57327/f85a3800-f10b-11be-5089-2a70ef14e8ae.png)

# 例えばこんな構成も
`Ohai`はローカルにインストールして叩きますが、`Specinfra`は`Backend`を切り替えてリモートから収集もできます。
なので、エージェント型と外部監視型を組み合わせたこんな構成も可能ですね。

![es-specinfra2.png](https://qiita-image-store.s3.amazonaws.com/0/57327/31ee02d6-d795-c724-e3f7-b99f771ddf2f.png)
※SSHは動作確認済み、WindowsはBackendは既にはあるけどHostInventoryの実装がまだ無い（2015.03.05現在）


# 最後に
SpecinfraのHost Inventoryは付加機能の一つであり、汎用コマンド実行フレームワークとして強力なプラットフォームの抽象化機構を持ちます。
その辺りを活かして、日々のオペレーションを助ける何かができないかなと思って色々弄ってみているのでした。