tjinjin's blog

インフラ要素多めの個人メモ

自分のマシンで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型と呼ばれています。

f:id:cross_black777:20171128214117p:plain

早速使ってみよう

最近proemtheus自体がアップデートされたので、そちらを使っていきます。docker-composeで動かせるrepositoryがあるので使います。

github.com

$ 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の画面を確認することができます。

f:id:cross_black777:20171130001050p:plain

解説

ここで終わったらあれなので、解説してきます。

docker-compose.ymlを見るとわかりますが、5つのコンテナで構成されています。簡単な模式図にすると下記のようになります。

f:id:cross_black777:20171127233333p:plain

それではそれぞれを見ていきます。

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を持っています。

f:id:cross_black777:20171130002011p:plain

grafana

prometheusのWebUIはそこまでリッチとは言えません。ダッシュボードを作り込みたいときに使えそうなのがgrafanaになります。

grafanaはdata sourceと呼ばれるデータの取得先を設定でき、ここにprometheusを設定することでgrafana上でmonitoringができるようになります。

grafanaにアクセスするとログイン画面が出てきます。admin/foobarでログインできます。(環境変数でパスワードを設定しています)

まずdata sourceを設定します。

f:id:cross_black777:20171129131235p:plain

設定は上記の通りです。

次にdashboardを作ってみます。ローカルに設定ファイルがあるのでUIからimportします。(今回はコピペ)

f:id:cross_black777:20171129115938g:plain

上記で作成したdashboardGrafana_Dashboard.jsonをコピペしたものです。操作の都合上ファイルの中身を貼り付けています。

まとめ

prometheusを実際に動かしながら学ぶ記事にしてみました。とりあえず動かすだけなら結構簡単ということがわかるかと思うので、ぜひお試しいただき快適なモニタリングライフを送っていきましょう!明日の記事はこちらからご覧下さい !執筆者はまだまだ募集しております!空いた日はexporterをひたすら紹介する記事をできる範囲で書きます。

qiita.com

参考リンク