自分のマシンでprometheusを動かしてみよう
About
こちらはprometheus Advent Calender1日目の記事です。第1日目ということで今回はdocker-composeを使ってprometheusを動かしてみよう編です。
12/2 20:30 誤記があったので修正しました(id:kutakutatriangle 様ありがとうございます!)
この記事の目標
prometheusをあまり触ったことない人がどんなものかを触りながら、各コンポーネントをなんとなく理解出来ている状態を目指す。
prometheusとは
google製 soundcloud製のモニタリングツールです。mackerelやdatadogなどとは違いいわゆるpull型のモニタリングツールです。前者はagentが情報を収集し、その情報を管理サーバなどに送る(push)ことでデータを集約しています。一方、後者のprometheusはexporterと呼ばれるplugin群がサーバで情報を収集しますが、データを送ったりはしません。データはprometheusサーバが各exporterのエンドポイントを叩いて収集する作りになっています。prometheusがexporterを叩いて回ってデータを収集するのでpull型と呼ばれています。
早速使ってみよう
最近proemtheus自体がアップデートされたので、そちらを使っていきます。docker-composeで動かせるrepositoryがあるので使います。
$ git clone https://github.com/vegasbrianc/prometheus.git $ git checkout version-2 # version2系用のbranchにcheckout
すでにdockerを使える状態であれば、docker-compose up
するだけですぐに起動できます。
$ docker-compose up
起動後、localhost:9090にアクセスするとprometheusの画面を確認することができます。
解説
ここで終わったらあれなので、解説してきます。
docker-compose.ymlを見るとわかりますが、5つのコンテナで構成されています。簡単な模式図にすると下記のようになります。
それではそれぞれを見ていきます。
prometheus
prometheusの本体です。このサーバを中心としてデータの収集が行われます。今回はdocker imageを使っていますがシングルバイナリで動かすことも可能です。
$ brew install prometheus # for mac
$ prometheus --config.file=promethes.yml
prometheusの設定を見ていきます。
# globalな設定 global: scrape_interval: 15s # By default, scrape targets every 15 seconds. evaluation_interval: 15s # By default, scrape targets every 15 seconds. # scrape_timeout is set to the global default (10s). # Attach these labels to any time series or alerts when communicating with # external systems (federation, remote storage, Alertmanager). external_labels: monitor: 'my-project' # alertのルールを定義しているファイル名を指定します rule_files: - 'alert.rules' # - "first.rules" # - "second.rules" # alertの設定です。ここではalertmanagerに対してhttp経由でアクセスするとなっています。"alertmanager:9093"の部分はdocker linkを使っている部分です。 alerting: alertmanagers: - scheme: http static_configs: - targets: - "alertmanager:9093" # prometheusがどこに対してデータを取得しに行くかを指定します。 # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: 'prometheus' - job_name: 'node' # Override the global default and scrape targets from this job every 5 seconds. scrape_interval: 5s # metrics_path defaults to '/metrics' # scheme defaults to 'http'. static_configs: - targets: ['localhost:9090','cadvisor:8080','node-exporter:9100']
scrape_configsに書いある設定ですが、現状の設定ではハードコートしたtargetに対してのみアクセスするようになっています。これだと動的にサーバが変化する環境では辛いのでService discoveryが欲しくなりますが、proemtheus側で様々なService discoveryを提供しています。
例えば、EC2にあるインスタンスに対してscrapeして欲しい場合、下記のように書くことができます。
scrape_configs: - job_name: 'node-exporter' ec2_sd_configs: - region: ap-northeast-1 - port: 9100
このように書くとprometheusがAWSのEC2をdescribeしてprivate IPを取得し、そのIPの9100に対してscrapeできるようになります。Tagを使った制御などもできるので、もう少し詳細な絞り込みも可能です。
prometheus/ec2.go at b3ff5f6b0ee4cef9923d3ec534abfa862486a579 · prometheus/prometheus · GitHub
アラートの設定はpromethesu側で持っています。1系ではyamlではなかったんですが、2系からyamlでかけるようになりました。
groups: - name: example rules: # Alert for any instance that is unreachable for >5 minutes. - alert: service_down expr: up == 0 for: 2m labels: severity: page annotations: summary: "Instance {{ $labels.instance }} down" description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 2 minutes." - alert: high_load expr: node_load1 > 0.5 for: 2m labels: severity: page annotations: summary: "Instance {{ $labels.instance }} under high load" description: "{{ $labels.instance }} of job {{ $labels.job }} is under high load."
ここでアラートの設定をすることで閾値を超えた場合にalertmanagerに発火されます。
alertmanager
alertmanagerアラートのハンドリングを行うコンポーネントです。prometheus内でalertを検知するとalertmanagerにPOSTされます。alertmanagerは実はWebUIも用意されているので、アラートの一覧を確認したりできます。
alertmanagerは/api/v1/alertsでPOSTを受け付けているのでcurlを使ってアラートを試すことも可能です。
$ cat alert.json [ { "labels": { "test": "test" }, "annotations": { "slack": "slack" }, "generatorURL": "<generator_url>" } ] $ curl -XPOST http://localhost:9093/api/v1/alerts -d @alert.json {"status":"success"}
alertmanagerもprometheus同様にymlで書かれた設定ファイルを読み込みます。
# ルーティングの設定。この例だとすべてのアラートは'slack' receiverに伝えられる route: receiver: 'slack' # 通知先の設定 receivers: - name: 'slack' slack_configs: - send_resolved: true username: '<username>' channel: '#<channel-name>' api_url: '<incomming-webhook-url>'
上記設定のままだとslack連携ができないのでwebhookのURLを取得し設定するとslack通知が試せます。
通知先に設定できる先にはslack以外にもemailやhipchatなど、多数対応しているおり便利です。
alertmanagerの通知で便利なのはgrouping機能です。これは似たようなアラートをまとめて通知できる機能です。短期間に通知が大量に来ると辛いですが、grouping機能である程度まとめられて通知が来るのでアラート地獄を回避できるのがよいですね。
node-exporter
node(ホストマシン)の状態を収集するexporterです。これを各nodeに入れておけばメトリックを収集できます。各exporterは/metricsというエンドポイントが実装されていて、prometheusはこのエンドポイントを叩くことでデータを収集しています。細かい設定無しでもそれなりに動きます。
cadvisor
containerの情報を取得するexporterです。各コンテナの情報が取得できます。こちらも入れておくと安心です。cadvisorもWebUIを持っています。
grafana
prometheusのWebUIはそこまでリッチとは言えません。ダッシュボードを作り込みたいときに使えそうなのがgrafanaになります。
grafanaはdata sourceと呼ばれるデータの取得先を設定でき、ここにprometheusを設定することでgrafana上でmonitoringができるようになります。
grafanaにアクセスするとログイン画面が出てきます。admin/foobarでログインできます。(環境変数でパスワードを設定しています)
まずdata sourceを設定します。
設定は上記の通りです。
次にdashboardを作ってみます。ローカルに設定ファイルがあるのでUIからimportします。(今回はコピペ)
上記で作成したdashboardはGrafana_Dashboard.json
をコピペしたものです。操作の都合上ファイルの中身を貼り付けています。
まとめ
prometheusを実際に動かしながら学ぶ記事にしてみました。とりあえず動かすだけなら結構簡単ということがわかるかと思うので、ぜひお試しいただき快適なモニタリングライフを送っていきましょう!明日の記事はこちらからご覧下さい !執筆者はまだまだ募集しております!空いた日はexporterをひたすら紹介する記事をできる範囲で書きます。
参考リンク
- Prometheus - Monitoring system & time series database
- Prometheus 実践入門 #hbstudy 79 / introduction-to-prometheus-practice // Speaker Deck
- Prometheusのec2 service discoveryを試す - 技術的なメモというか、忘却録
- Alertmanagerについて書いてみる - wyukawa’s blog
- GitHub - prometheus/node_exporter: Exporter for machine metrics
- GitHub - google/cadvisor: Analyzes resource usage and performance characteristics of running containers.
- Grafana - The open platform for analytics and monitoring