在使用Docker Compose构建ELK(ElasticSearch、Logstash、Kibana)+fluentd环境的同时,试着收集CloudWatch的统计数据进行尝试

我之前一直对ELK(ElasticSearch,Logstash,Kibana)的环境感兴趣,现在我使用Docker Compose使其能够在任何地方轻松构建。

另外,我也想试试使用Logstash或fluentd的插件进行数据收集和可视化。我试着收集了AWS的CloudWatch统计数据。

环境

下面是我们试验的环境和工具版本。

環境バージョンなどOSEI Capitan(10.11.1)ElasticSearch2.0.0Logstash2.0.0Kibana4.2.0td-agent0.12.12Docker Engine1.8.3Docker Machine0.4.1Docker Compose1.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/。

如果您的Mac已经安装了homebrew cask,您也可以使用以下命令进行安装。
(我是用这个方法安装的)

使用Homebrew Cask安装Docker Toolbox:
$ brew cask install dockertoolbox.

当安装完毕后,我们将在VirtualBox中创建一个运行Docker主机的虚拟机。这次我以dev为名称创建了它。
$ docker-machine create -d virtualbox dev

我在Windows 10上安装了Docker Toolbox来尝试,和在Mac上一样成功了。
(我使用了cygwin作为终端)

创建各自的容器

每个Dockerfile

这次做的东西如下所示。我已经将其注册为GitHub存储库。

我打算尝试添加fluentd以配合ELK。

我也写了每个版本构建后的图像大小。

ElasticSearch 314 MB

Logstash 422 MB

Kibana 321 MB

fluentd 125 MB

这次为了学习的目的,我尝试以Ubuntu的映像为基础进行构建,但映像的大小变得很大。。。
顺便提一下,下面是全新的官方映像。与Kibana完全不同呢。

ElasticSearch公式
153MB

Logstash公式
206MB

Kibana公式
89MB

fluentd公式
v0.12.16で178 MB

将其注册到DockerHub的自动构建中

为了在运行Docker Compose时自动从DockerHub获取映像,我们需要将GitHub仓库注册到DockerHub。
这样做的好处是,当我们将特定的分支推送到GitHub的特定仓库时,映像将自动在DockerHub上构建和保存。

只需要简答。

dockerhub4.png

只需这样就可以了。

使用Docker Compose进行构建

接下来,我们将创建一个用于在Docker Compose中构建的YAML文件。

这次的集装箱关系如下图所示。

Pasted_Image_11_7_15__9_54_PM.png

由于红色箭头表示的是容器之间的通信,所以必须知道对方的IP地址才能进行通信。
因此,需要在链接选项中指定如下。

  links:
    - elasticsearch:docker-elasticsearch

如果你写了这个,你就可以通过docker-elasticsearch这个主机名来获取elasticsearch容器的IP地址。
(elasticsearch容器的IP地址已经写在容器内的/etc/hosts中。)

考虑到这一点,我们最终将被传递给Docker Compose的YAML文件(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的统计数据,并将其输出到Elasticsearch容器中。

日志管道

在搜索中发现了以下的Input插件:logstash-input-cloudwatch。

这次我决定试试看这个。

然而,出现了问题,logstash-input-cloudwatch.gemspec 文件中所指定的 logstash 版本需要在 1.4.0 及以上,但不包括2.0.0。

于是,我决定先将其升级到2.0.0版本并进行构建测试。
我对下面的一行进行了以下修改。

  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命令进行安装。

您不需要额外安装输出插件,因为您可以直接将输出发送到ElasticSearch,默认功能已经包含了这一功能。

我按照下述方式创建了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的CloudWatch中,namespace被设置为获取AWS/EC2的统计数据。
在output中,将数据输出到Elasticsearch和标准输出。
由于在Elasticsearch的hosts中设置了值为docker-elasticsearch,因此通过/etc/hosts进行名称解析。

在尝试执行后,它正常运作,并以以下方式被输入到ElasticSearch中。(指的是CPU利用率)

{
  "_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没有本该支持,所以有点担心的。。。

流利的日志收集器

在尝试搜索时,我也找到了以下作为输入插件的云监控插件。

另外,还需添加一个插件才能将数据发送到ElasticSearch中。一个选择是fluent-plugin-elasticsearch。

这些安装在Dockerfile中进行。

我已将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>

首先,在第一个来源中,与logstash时一样,我们使用AWS/EC2。在第二个来源中,我们使用AWS/Billing。 AWS/Billing是当前的结算金额。要获取AWS/Billing的命名空间统计数据,需要先进行以下设置。请参考下面的链接:
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/DeveloperGuide/monitor_estimated_charges_with_cloudwatch.html

就Output而言,与Logstash时一样,将docker-elasticsearch设置为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

 

    1. $ docker-machine start dev

将 docker machine 的环境变量注册到主机
$ eval “$(docker-machine env dev)”

在 docker machine 上进行端口转发
由于容器正在 dev VM 上运行,
我们需要在 VM 主机的 Mac 上连接到 VM 的 Kibana 的 5601/tcp 端口。
在另一个终端中输入以下命令。
$ ssh docker@$(docker-machine ip dev) -L 5601:localhost:5601
在此期间,将要询问密码, 默认密码是 tcuser。
克隆 docker compose 仓库
$ git clone -b 1.0.0 git@github.com:khiraiwa/compose-elk.git
$ cd compose-elk
将 docker-compose.yml 中的 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 替换为正确的值(两处)
使用 docker compose 启动
$ docker-compose up -d
然后,将会开始从 DockerHub 拉取镜像,一旦完成,容器将会启动。

修改tg-agent的配置并重新启动。

由于没有自动更改td-agent.conf的实例ID,导致发生了手动操作。

    1. 由于之前进行了端口转发的终端仍然登录在dev虚拟机上,现在打开/data_tdagent/td-agent.conf文件(使用vi或者其他编辑器)。一处地方的dimensions_value应该是i-XXXXXXXX,将其替换为正确的实例ID,并保存。(下面是一个示例)

dimensions_value i-fdb70939

重新启动容器。在执行Docker Compose的机器上,运行以下命令,重新启动fluentd容器。

$ docker-compose restart tdagent

尝试在Kibana中观察一下

kibana3.png

停止 Docker

    1. 使用Docker Compose停止

 

    1. $ docker-compose stop

停止Docker Machine
$ docker-machine stop dev

如果需要删除Docker主机的虚拟机
$ docker-machine rm dev

最后

我可以通过单击一个按钮来构建ELK(+fluentd)环境,使其在任何地方都可以使用。
(顺便提一下,因为尚未在代理环境下进行测试,所以可能无法运行。)

顺便提一下,这次我试了一下获取CloudWatch的统计数据,只需要注册AWS的ACCESS_KEY就好,用SaaS服务相当方便呢。
此外据说Grafana已经正式支持CloudWatch了。
在Grafana中查看CloudWatch(连接设置篇)。

如果仅需要两周的最大显示间隔,那么2015年10月发布的CloudWatch仪表板已经足够了。

bannerAds