Consulをサービスディスカバリに使い、Consul TemplateでPrometheusの設定ファイルを生成するという構成で、ノードが増加しても自動的にPrometheusの収集対象が増えるような構成を作ってみました。
Prometheus
PrometheusはSoundCloudが開発を行っている監視システムです。 Graphiteと違いPrometheusはPull型のアーキテクチャをとっています。Prometheusサーバがexporterと呼ばれる所謂エージェントに値を取りに行く形です。
Push型に比べれば、Pull型は負荷が集中するので収集できるノード数は少なくなると思います。 ただ、Push型は何らかの理由でメトリクスデータをPushできなくなったときに、検知が困難になるというデメリットもあります。 Pull型であれば取れなかったことが検知でき、その理由も調べることが可能です。
時系列データストアは自前の物を利用しているようですが、OpenTSDBも利用可能らしいです。 独自のクエリをサポートしており、収集したデータを加工して表示することも出来ます。 グラフ表示機能はPrometheusサーバにも簡易的な物が用意されていますが、 Rails で書かれた PromDash というものを利用するのが良さそうです。 その他、Push型のデータを収集するための pushgateway や、アラートを出すための alertmanager もあります。
今回は Prometheus Server と node_exporter を利用します。
動作環境
今回は AWS EC2 を使用します。
- Amazon EC2
- Amazon Linux 2015.03.1
- Prometheus 0.14.0
- node_exporter 0.9.0
- Consul 0.5.2
- Consul Template 0.10.0
Tags
EC2のタグは以下のようにしておきます。
Node | Tag | Description |
---|---|---|
server1 | consul-leader: True | Consul Server, Prometheus Server |
node1 | - | Consul Agent, node_exporter |
node2 | - | Consul Agent, node_exporter |
Ports
Program | Protocol | Port |
---|---|---|
Prometheus Server | TCP | 9090 |
node_exporter | TCP | 9100 |
Consul Server | TCP | 8300, 8301, 8400, 8500, 8600 |
UDP | 8600 | |
Consul Agent | TCP | 8400, 8500 |
UDP | 8600 |
Consul Server と Consul template, Prometheusの設定
ConsulはPrometheusに比べれば有名なので説明は割愛。 インストール手順も割愛。
まずは、ConsulとConsul Templateが起動するようにします。 Consul Serverのアドレスを取得するためにEC2のタグを参照するので、IAM Roleを付けておきます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances"
],
"Resource": [
"arn:aws:ec2:::*"
]
}
]
}
Consul Server
Upstart を使用し Consul Serverを起動させます。
- /etc/init/consul_server.conf
description "Consul"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
if [ -f "/etc/service/consul" ]; then
. /etc/service/consul
fi
# Make sure to use all our CPUs, because Consul can block a scheduler thread
export GOMAXPROCS=`nproc`
exec /usr/local/bin/consul agent \
-server \
-data-dir="/var/lib/consul/" \
-bootstrap-expect 1 \
-config-dir="/etc/consul.d/" \
${CONSUL_FLAGS} \
>>/var/log/consul.log 2>&1
end script
$ sudo initctl start consul_server
Consul Template
Consul templateはConsulのクラスタ情報を元にファイルを生成してくれます。 クラスタに変化があると、ファイルを更新し、指定したコマンドを実行してくれます。
- /etc/init/consul_template.conf
description "Consul template"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
exec /usr/local/bin/consul-template \
-consul 127.0.0.1:8500 \
-template "/opt/templates/prometheus.ctmpl:/etc/prometheus/prometheus.yml:initctl restart prometheus" >> /var/log/ctemplate.log 2>&1
end script
$ sudo initctl start consul_template
Prometheus
テンプレートの用意
Consul TemplateでPrometheusのコンフィグを生成するためテンプレートを用意します。
- /opt/templates/prometheus.ctmpl
global:
scrape_interval: 1s
evaluation_interval: 3s
labels:
monitor: 'web monitor'
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 10s
scrape_timeout: 10s
target_groups:
- targets: ['localhost:9090']
- job_name: 'web'
scrape_interval: 10s
scrape_timeout: 10s
target_groups:
- targets: [{{range service "web"}}'{{.Address}}:9100',{{end}}]
service名は web
としています。
この値は後述する Consul Agent とあわせる必要があります。
scrape_interval
は値を取得する間隔を指定します。
Prometheus にはConsulと連携する機能があるようなのですが、イマイチ使い方が判りませんでした。 これが使えれば、Consul Templateは不要かもしれません。
Prometheusのインストール
ここはまあ、普通に。 Ansible Playbookとかにしておくと良いかもしれません。
$ sudo yum install golang git mercurial gcc-c++ epel-release
$ sudo yum install --enablerepo=epel protobuf
$ cd /usr/local/src
$ git clone https://github.com/prometheus/prometheus.git
$ cd prometheus
$ make build
$ sudo useradd -s /bin/false -m prometheus
$ sudo mkdir /etc/prometheus
初期の設定ファイルがないと起動しないので、作成しておきます。
- /etc/prometheus/prometheus.yml
global:
scrape_interval: 1s
evaluation_interval: 3s
labels:
monitor: 'web monitor'
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 10s
scrape_timeout: 10s
target_groups:
- targets: ['localhost:9090']
PrometheusもUpstartで起動させます。
- /etc/init/prometheus.conf
description "Prometheus"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
/usr/local/src/prometheus/prometheus -config.file=/etc/prometheus/prometheus.yml
end script
$ sudo initctl start prometheus
Consul Agentの設定とサービスの定義
Consul Agent
こちらもConsul Serverと同じく Upstart で起動させます。 起動する際に、Consul Serverのアドレスを AWS CLI を使って取得し、クラスタへJoinさせます。
- /etc/init/consul_agent.conf
description "Consul"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
if [ -f "/etc/service/consul" ]; then
. /etc/service/consul
fi
# Make sure to use all our CPUs, because Consul can block a scheduler thread
export GOMAXPROCS=`nproc`
JOIN_TO="$(aws ec2 describe-instances --query 'Reservations[].Instances[?State.Name==`running`].PrivateIpAddress' --output text --filters 'Name=tag:consul-leader,Values=true')"
exec /usr/local/bin/consul agent \
-data-dir="/var/lib/consul" \
-config-dir="/etc/consul.d" \
-join ${JOIN_TO} \
${CONSUL_FLAGS} \
>>/var/log/consul.log 2>&1
end script
ついでにサービスの定義も行います。 Consulは簡易なサービスのチェックも行えるようになっております。
- /etc/consul.d/web.json
{
"services":[
{
"name": "Web",
"port": 80,
"check": {
"script": "curl -s http://localhost/ -o /dev/null",
"interval": "10s"
},
"tags": ["http"]
}
]
}
$ sudo initctl start consul_agent
これらを組み込んだAMIを作っておいて、あとはインスタンスを起動していけば自動的にどんどん監視対象が増えていきます。
PromDash
PromDashというダッシュボード的なWebインターフェイスが提供されています。 PromDashはRailsで出来ており、動かすのがめんどうなので、Dockerで動かすのがオススメです。
PromDash内のデータベースには、PrometheusサーバのURLと表示するグラフに関する情報のみ記録されてるだけなので、Dockerコンテナが消えても、収集したメトリクスは消えません。
$ docker pull prom/promdash
$ docker run -v /tmp/prom:/tmp/prom -e DATABASE_URL=sqlite3:/tmp/prom/file.sqlite3 prom/promdash ./bin/rake db:migrate
$ docker run -d -p 3000:3000 -v /tmp/prom:/tmp/prom -e DATABASE_URL=sqlite3:/tmp/prom/file.sqlite3 prom/promdash
所感
監視を行うのに一通りの機能は揃っていますが、長期的に運用するときにどのような問題が出るか不透明な点はあります。 短期間使ってみた感じでは、短期間のメトリクス収集にはとても有用な感じがしました。 クエリによる値の集計なども簡単にできてよいです。
プロダクション環境では本格的に使ったわけではありませんが、イベントなどで使うインフラのメトリクス収集に何回か利用しています。
使い分けとしては、インスタントにメトリクスをとりたい場合は pcp + Vector, 短期間のメトリクス収集には Prometheus, 長期的な監視やメトリクス収集は Zabbix や Sensu + Graphite がよいかなと。
ほんとはデータの管理とかやりたくないので、Mackerel, Datadog が安くなればいいですね。