LoginSignup
51
48

More than 5 years have passed since last update.

ELK(ElasticSearch, Logstash, Kibana)+fluentdの環境をDocker Composeで構築しつつ、試しにCloudWatchの統計データを収集してみた

Last updated at Posted at 2015-11-08

前々から気になっていたELK(ElasticSearch, Logstash, Kibana)の環境をDocker Composeを使ってどこにでも簡単に構築できるようにしてみました。

また、Logstashやfluentdのプラグインを使ったデータ収集と可視化も試してみようと思い、試しにAWSのCloudWatchの統計データを収集してみました。

環境

今回試した環境と、ツール類のバージョンは下記のとおりです。

環境 バージョンなど
OS EI Capitan(10.11.1)
ElasticSearch 2.0.0
Logstash 2.0.0
Kibana 4.2.0
td-agent 0.12.12
Docker Engine 1.8.3
Docker Machine 0.4.1
Docker Compose 1.4.2

表のDockerについて。。。

  • Engineはいわゆる普通のDocker。Dockerの実行環境です。
  • MachineはローカルやAWSなどの別環境にDockerのホストマシンを構築するツール。
    通常、MacやWindowsでDockerを使う場合は、このMachineを用いて、ローカルのVirtualBoxにDockerホストのVMを作って、それに対して、dockerコマンドを実行していきます。
  • Composeは複数のコンテナのパラメータをYAMLファイルに記述しておいて、ワンボタンで環境構築するものです。

はじめにdockerの環境を整えておく

Dockerで構築しておくと何度も同じインストール作業をしなくてよくなります。

MacだとDocker Toolboxをインストールすれば、Docker Engine, Machine, Composeの準備がすべて整います。
https://docs.docker.com/mac/step_one/

homebrew caskが使える場合は、下記でもインストールできます。
(私はこちらでやりました)

$ brew cask install dockertoolbox

インストールが終わったら、Dockerのホストが動作するVMをVirtualBoxに作成しておきます。
今回devという名前で作成しました。
$ docker-machine create -d virtualbox dev

Windows10でもDocker Toolboxをインストールして試してみましたが、Macと同じようにできました。
(ターミナルにはcygwinを使用しました)

それぞれのコンテナを作る

それぞれのDockerfile

今回作ったものは、下記になります。GitHubのリポジトリとして登録しています。
ELKに合わせてfluentdも試してみようと思い追加しています。
それぞれのビルド後のイメージサイズも書いてみました。

今回は勉強のためにubuntuのイメージをベースに構築してみましたが、イメージのサイズが大きくなってしまいました。。。:sweat:
ちなみに、下記まっさらな公式イメージ。Kibanaとか全然違いますね。

DockerHubのAutomated Buildに登録しておく

Docker Composeを実行した際にDockerHubから自動的にイメージを取ってくるようにするため、GitHubのリポジトリをDockerHubに登録しておきます。

これをやっておくと、GitHubの特定のリポジトリの特定のブランチにPushしたタイミングで自動的にDockerHubでイメージがビルドされ保存されるようになります。

方法は、とても簡単で、

  1. まず、DockerHubにログインします。
  2. 下記のように"Create"ボタンの右の▼を押して、 dockerhub1.png
  3. "Create Automated Build"を選択します。 dockerhub2.png
  4. すでにGitHubアカウントでログインしていたり、ひも付けをおこなっていると、下記のようにリポジトリ一覧が表示されます。
    Automated Buildしたいリポジトリを選択します。 dockerhub3.png
  5. 必要内容を記述して、"Create"ボタンを押します。 dockerhub4.png

これだけで完了です。

Docker Composeで構築する

次にDocker Composeで構築するためのYAMLファイルを作成します。

今回のコンテナの関係は下記の図のようになっています。

Pasted_Image_11_7_15__9_54_PM.png

赤い矢印についてはコンテナからコンテナへの通信なので、相手のIPアドレスがわからないと通信できません。
そのため、下記のようにlinkオプションで指定してやる必要があります。

  links:
    - elasticsearch:docker-elasticsearch

これを書いておけば、docker-elasticsearchというホスト名で、elasticsearchのコンテナのIPアドレスが引けるようになります。
(コンテナ内の/etc/hostsにelasticsearchのコンテナのIPアドレスが書かれていました。)

上をふまえて、最終的にDocker Composeに渡すYAMLファイル(docker-compose.yml)は下記のようにしました。

docker-compose.yml
# elasticsearch
elasticsearch:
  image: khiraiwa/docker-elasticsearch:1.0.0
  volumes:
    - /data_elasticsearch:/data_elasticsearch
  ports:
    - "9200:9200"
    - "9300:9300"

# kibana
kibana:
  image: khiraiwa/docker-kibana:1.0.0
  volumes:
    - /data_kibana:/data_kibana
  ports:
    - "5601:5601"
  links:
    - elasticsearch:docker-elasticsearch

# logstash
logstash:
  image: khiraiwa/docker-logstash:1.0.0
  volumes:
    - /data_logstash:/data_logstash
  links:
    - elasticsearch:docker-elasticsearch
  environment:
    - AWS_ACCESS_KEY_ID=dummy
    - AWS_SECRET_ACCESS_KEY=dummy

# tdagent
tdagent:
  image: khiraiwa/docker-tdagent:1.0.0
  volumes:
    - /data_tdagent:/etc/td-agent
  links:
    - elasticsearch:docker-elasticsearch
  environment:
    - AWS_ACCESS_KEY_ID=dummy
    - AWS_SECRET_ACCESS_KEY=dummy

(GitHubにあげておきました。
https://github.com/khiraiwa/compose-elk/blob/5694e5c09b9e679b674d4a916582802f24d6e855/docker-compose.yml)

CloudWatchの統計データを取得してみる

動作確認のため、LogstashやfluentdのコンテナでCloudWatchの統計データをInputして、ElasiticSearchのコンテナにOutputするようにしてみました。

Logstash

検索すると、下記のInputプラグインが見つかりました。
logstash-input-cloudwatch

今回はこれを使ってみることに。

しかし、問題があり、logstash-input-cloudwatch.gemspecに書かれているlogstashの対応バージョンは1.4.0以上2.0.0未満でした。

そこで、とりあえず、これを2.0.0に対応させてビルドしてみることに。
下の方の一行を下記のように修正しました。

logstash-input-cloudwatch.gemspec
  s.add_runtime_dependency "logstash-core", '>= 1.4.0', '<= 2.0.0'

そして下記のコマンドでビルド。


$ [logstashへのパス]/vendor/jruby/bin/gem build logstash-filter-awesome.gemspec

すると、logstash-input-cloudwatch-0.2.2.gemが出来上がったので、下記でインストール。


$ [logstashへのパス]/bin/plugin install /your/local/plugin/logstash-filter-awesome.gem

今回のDockerイメージでは、Dockerfileにてビルド済みファイルをADDしてインストールするようにしています。

Outputのプラグインの追加インストールは必要なく、デフォルトでElasticSearchにOutputできます。

logstash.confは下記のようにしてみました。

logstash.conf

input {
  cloudwatch {
    tag_name => "Name"
    tag_values => "*"
    region => 'us-west-2'
    interval => 900
    period => 60
    namespace => 'AWS/EC2'
    metrics => [ 'CPUCreditUsage','CPUCreditBalance','CPUUtilization','DiskReadOps','DiskWriteOps','DiskReadBytes','DiskWriteBytes','NetworkIn','NetworkOut','StatusCheckFailed','StatusCheckFailed_Instance','StatusCheckFailed_System' ]
    statistics => [ 'SampleCount', 'Average', 'Minimum', 'Maximum', 'Sum' ]
  }
}

output {
  elasticsearch { hosts => 'docker-elasticsearch:9200' }
  stdout { codec => rubydebug }
}

inputのcloudwathではnamespaceがAWS/EC2の統計データを取得するようにしています。
outputではelasticsearchへの出力と標準出力を行っています。
elasticsearchのhostsにはdocker-elasticsearchという値を設定しているので、/etc/hostsにより名前解決されます。

実行してみたところ正しく動作し、ElasticSearchには下記のような形でInputされていました。(CPUUtilizationのもの)

{
  "_index": "logstash-2015.11.04",
  "_type": "logs",
  "_id": "AVDSjQcXo0IJOX5JTEN8",
  "_score": null,
  "_source": {
    "timestamp": "2015-11-04 12:43:00 +0000",
    "sample_count": 5,
    "unit": "Percent",
    "minimum": 0,
    "maximum": 0.17,
    "sum": 0.17,
    "average": 0.034,
    "@version": "1",
    "@timestamp": "2015-11-04T12:43:00.000Z",
    "metric": "CPUUtilization",
    "instance": "i-fdb70939",
    "Name": "Test"
  },
  "fields": {
    "@timestamp": [
      1446640980000
    ]
  },
  "sort": [
    "43"
  ]
}

このプラグイン、試してみたところ、tag_valuesのところにワイルドカードを指定可能なようで、なかなか便利でした。

※本来、Logstashの2.0.0には対応していなかったはずなのでちょっと心配ですが。。。

fluentd

こちらも探してみるとInputのプラグインとして下記が見つかりました。
fluent-plugin-cloudwatch

また、ElasticSearchへのOutputにも別途プラグインの追加が必要です。
fluent-plugin-elasticsearch

これらはDockerfile中でインストールするようにしています。

tdagent.confは下記のようにしました。

tdagent.conf

<source>
  type cloudwatch
  tag  cloudwatch.ec2

  aws_key_id  YOUR_AWS_KEY_ID
  aws_sec_key YOUR_AWS_SECRET_KEY

  cw_endpoint monitoring.us-west-2.amazonaws.com

  namespace AWS/EC2
  metric_name CPUCreditUsage,CPUCreditBalance,CPUUtilization,DiskReadOps,DiskWriteOps,DiskReadBytes,DiskWriteBytes,NetworkIn,NetworkOut,StatusCheckFailed,StatusCheckFailed_Instance,StatusCheckFailed_System,
  dimensions_name InstanceId
  dimensions_value i-XXXXXXXX
  statistics Average
  period 300
  interval 300
</source>

<source>
  type cloudwatch
  tag  cloudwatch.billing

  aws_key_id  YOUR_AWS_KEY_ID
  aws_sec_key YOUR_AWS_SECRET_KEY

  cw_endpoint monitoring.us-east-1.amazonaws.com

  namespace AWS/Billing
  metric_name EstimatedCharges
  dimensions_name Currency
  dimensions_value USD
  statistics Average
  interval 7200
  period 21600
</source>

<match cloudwatch.**>
  type elasticsearch
  host docker-elasticsearch
  port 9200
  index_name fluentd
  type_name fluentd
  logstash_format true
  logstash_prefix tdagent
  request_timeout 5s # defaults to 5s
  reload_connections true # defaults to true

  # Buffered output options
  buffer_type memory
  flush_interval 60
  retry_limit 17
  retry_wait 1.0
  num_threads 1
</match>

まず、一つ目のsourceではlogstashの時と同じくAWS/EC2のものを、二つ目のsourceではAWS/Billingを取るようにしています。
AWS/Billingは現時点の請求額です。
AWS/Billingのnamespaceの統計データを取るには、あらかじめ下記の設定が必要です。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/DeveloperGuide/monitor_estimated_charges_with_cloudwatch.html

Outputについて、Logstashのときと同様にelasticsearchのhostにはdocker-elasticsearchを設定しているので、/etc/hostsにより名前解決されます。

実行してみたところ正しく動作し、ElasticSearchには下記のようにインプットされていました。

{
  "_index": "tdagent-2015.11.04",
  "_type": "fluentd",
  "_id": "AVDSmNVAo0IJOX5JTEYl",
  "_score": null,
  "_source": {
    "CPUUtilization": 0.032,
    "@timestamp": "2015-11-04T12:53:00+00:00"
  },
  "fields": {
    "@timestamp": [
      1446641580000
    ]
  },
  "sort": [
    1446641580000
  ]
}

ちなみに、Logstashで使えたようなワイルドカードは使えないようだったので、とりあえずtdagent.confのdimensions_valueをi-XXXXXXXXとしています。
(実行時に修正して、td-agentのコンテナを再起動する必要あり。。。)

実際に構築してみる

一連の手順を詳しく書くと長いように感じますが、実際に入力するdocker-composeのコマンドはとてもシンプルです。

dockerの準備

  1. docker machineの起動
    $ docker-machine start dev
  2. docker machineの環境変数をホストマシンに登録
    $ eval "$(docker-machine env dev)"
  3. docker machineにポートフォワーディング
    コンテナがたちあがるのは、devというVM上なので、
    devというVMのKibanaの5601/tcpポートをVMのホストのMacから繋げられるようにしておきます。
    別のターミナルを開いて、下記を入力。
    $ ssh docker@$(docker-machine ip dev) -L 5601:localhost:5601
    このとき聞かれるパスワードはデフォルトだとtcuserです。
  4. docker composeのリポジトリをclone
    $ git clone -b 1.0.0 git@github.com:khiraiwa/compose-elk.git
    $ cd compose-elk
    docker-compose.ymlのAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYを正しいものに書き換えます。(二か所)
  5. docker composeで起動
    $ docker-compose up -d
    すると、DockerHubからのイメージのPullが始まり、それが完了するとコンテナが立ち上がります。

tg-agentのconfを書き換えて再起動

自動でtd-agent.confのインスタンスIDを書き換えるようにしていないので、手作業が発生してしまいました :sweat:

  1. 先ほどポートフォワーディングしたターミナルはdevのVMにログインしたままになっているので、これで/data_tdagent/td-agent.confを開きます。(viなどで)
  2. dimensions_valueがi-XXXXXXXXになっている箇所が一つあるので、これを正しいインスタンスIDに書き換えて、保存します。(下記、例)
    dimensions_value i-fdb70939
  3. コンテナを再起動します。Docker Composeを実行したマシンで、下記を実行して、fluentdのコンテナを再起動します。
    $ docker-compose restart tdagent

Kibanaで見てみる

  1. Webブラウザから下記のURLにアクセスします。
    http://localhost:5601/
    すると、Kibanaが開きます。
    しかし、初回だと、まだindexパターンの設定を行っていないので、データをみることはできません。
  2. indexパターンの設定を行う
    まず、"Settings"のメニューを選択します。 kibana1.png 続いて、indexのパターンを作成します。
    今回Logstashはlogstash-*、fluentdはtdagent-*のindexのフォーマットでデータをInputするように設定しているため、それを入力して作成します。 "Create"ボタンが緑色にならず、押せなかった場合はまだデータがInputされていません。 kibana2.png
  3. データを確認する
    "Discover"を選択し、先ほど作成したindexパターンを選択します。
    すると、図のようにデータのInputのグラフと、実際のパラメータが表示されるので確認できます。 kibana3.png
  4. グラフ化
    Visualizeでグラフの作成が可能です。そして、それをDashboardで自由に表示できます。 (ここについては割愛します)

dockerの終了

  1. docker composeで終了
    $ docker-compose stop
  2. docker machineの終了
    $ docker-machine stop dev
  3. dockerホストのVMも削除する場合は
    $ docker-machine rm dev

最後に

これで、どこでもワンボタンで構築できるELK(+fluentd)の環境を作ることができました。
(ちなみに、まだProxy環境下ではテストしていないので動かないかもです。)

ちなみに、今回はCloudWatchの統計データ取得を試しにやりましたが、AWSのACCESS_KEYを登録するだけでいい、SaaSのサービスの方が相当楽ですね:sweat:
またGrafanaだと、CloudWatchが正式にサポートされているそうです。
GrafanaでCloudWatch見る(接続設定編)

まあ、そもそも最大表示間隔が2週間でよければ、2015年10月に発表されたCloudWatch Dashboardsで十分なのですが。

51
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
48