今回はモニタリングツールであるPrometheusを紹介します。
Prometheusとは
Prometheus は、もともとSoundCloudに依って開発されたモニタリングツールです。他のモニタリングツールにない特徴として、後述するクライアントであるExporterからメトリック(データ)を自分で取得しにいくpull型の構造を持っています[1] 。
Prometheus自体は大雑把に以下の3つの部分から構成されています。
メトリック取得対象(Exporter)を見つけ、取得する部分
取得したメトリックを蓄える時系列データベース
時系列データベースに蓄えたメトリックを検索するためのエンドポイント(HTTPサーバ)
Prometheus自体はgolangで書かれているため、ただ一つのバイナリを起動するのみで動作します。このためコンテナとの相性がよく、またパッケージの依存関係などを考慮する必要がないため既存の環境で試しに導入するハードルが比較的低いと言えます。
Prometheusのインストール
Ubuntuでは主に以下の方法でPrometheusがインストールできます。
aptレポジトリとsnapパッケージにあるPrometheusはいずれもバージョンが若干古いので、今回は手動で2019年3月時点で最新のver. 2.8.0のインストールを行います。前述のとおりにPrometheusそのものはバイナリ一つ起動すれば良いため、基本的にはバイナリと設定ファイル、daemon化のためのsystemd service unit fileの設置のみで作業が済みます[2] 。
まず、Prometheusを動作させるユーザとグループを作成します。
$ sudo groupadd prometheus
$ sudo useradd -d /var/lib/prometheus -g prometheus -s /bin/false -m prometheus
upstreamよりバイナリをダウンロードします。実際には以下が含まれます。
Promehteus本体のバイナリ
設定ファイルのサンプル(prometheus.yml)
ユーティリティであるpromtoolのバイナリ
エンドポイントの画面を提供するconsole template(consoles) とそのライブラリ(console_libraries)
$ wget https://github.com/prometheus/prometheus/releases/download/v2.8.0/prometheus-2.8.0.linux-amd64.tar.gz
$ tar xf prometheus-2.8.0.linux-amd64.tar.gz
$ ls -1 prometheus-2.8.0.linux-amd64
console_libraries
consoles
LICENSE
NOTICE
prometheus
prometheus.yml
promtool
Prometheusとpromtoolのバイナリをパスが通った場所へ設置します。
$ sudo cp prometheus promtool /sbin/
$ sudo chown root:root /sbin/prometheus /sbin/promtool
設定ファイルディレクトリと時系列データベースのデータディレクトリを作成します。
$ sudo mkdir /etc/prometheus
$ sudo mkdir /var/lib/prometheus/data
$ sudo chown -R prometheus:prometheus /var/lib/prometheus/data
サンプルの設定ファイルと、console templateを設定ファイルディレクトリへ設置します。
$ sudo cp -r prometheus.yml consoles console_libraries /etc/prometheus/
$ sudo chown -R root:prometheus /etc/prometheus
最後に/etc/systemd/system/prometheus.serviceへsystemdのservice unit fileを設置します。
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network-online.target
[Service]
User=prometheus
ExecStart=/sbin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/data --web.console.templates=/etc/prometheus/consoles --web.console.libraries=/etc/prometheus/console_libraries
ExecStop=/bin/kill -TERM ${MAINPID}
ExecReload=/bin/kill -HUP ${MAINPID}
[Install]
WantedBy=multi-user.target
更新したunit fileを読み込み、Prometheusの起動とその確認を行います。
$ systemctl daemon-reload
$ systemctl start prometheus.service
$ systemctl status prometheus.service
ブラウザでPrometheusが起動しているホストの9090番ポートへアクセスしてみましょう。
すると図1 のようなダッシュボードが表示されるはずです。ダッシュボードからは後述のPromQLをクエリしたり、メトリック取得対象のリストや状態を確認できます。
図1 PrometheusのHTTPエンドポイントのダッシュボード
また、consoles/prometheus.htmlへアクセスすると、先程設置したconsole templateによって生成されたPromehtuesのStatusが確認できます。
図2 Prometheusのconsole template
Node_Exporterのインストール
次にメトリック収集対象としてExporterをインストールします。
Exporterの実体はPrometheusから[3] HTTP GETを受けると関連するメトリックを収集し、Prometheusが解釈可能なテキストデータとして渡すというHTTPサーバです。
[3] HTTP GETする主体は問わないため、必ずしもPrometheusである必要はありません。また、Exporter自体はACL機能を持たないため、アクセス制限をかけたい場合は別途ファイアーウォール等を使用する必要があります。
Exporterは公式・サードパーティのものを含めて様々なサービスや装置のメトリックを収集・提供するものが存在しています 。また、Prometheusそのものも自分自身のメトリックを収集するExporterとして機能しています。今回は各ホストのCPUやメモリの使用量等のハードウェア関連のメトリックを収集するNode_Exporterをインストールします。
Node_Exporterもapt、snapパッケージ 、Docker image が用意されています。今回はこちらに関してもPrometheus同様に、2019年3月時点で最新のver. 0.17.0のpre-compiledバイナリ[4] を使用します。
[4] Node_Exporterはver. 0.16.0とそれ以前でメトリック名に破壊的な変更が加わっている ため注意が必要です。2019年3月時点では完全に新規の導入であれば0.16.0より新しいバージョンを選択するのが良いでしょう。
先程Prometheusをインストールしたホストでupstreamよりバイナリをダウンロードし、Node_Exporterのバイナリを設置します。
$ wget https://github.com/prometheus/node_exporter/releases/download/v0.17.0/node_exporter-0.17.0.linux-amd64.tar.gz
$ tar xf node_exporter-0.17.0.linux-amd64.tar.gz
$ sudo cp node_exporter-0.17.0.linux-amd64/node_exporter /sbin/
$ sudo chown root:root /sbin/node_exporter
/etc/systemd/system/node_exporter.serviceへsystemdのservice unit fileを設置します。
[Unit]
Description=Node Exporter for Prometheus
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=/sbin/node_exporter
PrivateTmp=true
[Install]
WantedBy=multi-user.target
そして以下の手順でNode_Exporterを起動します。
$ systemctl daemon-reload
$ systemctl start node_exporter.service
起動できたらブラウザでNode_Exporterが起動しているホストの9100番ポートの/metricsへアクセスしてみましょう。すると図3のようなメトリックが画面に表示されます。
図3 Node_Exporterのメトリック
また、curlなどを使用して直接HTTP GETでも確認できます。
$ curl localhost:9100/metrics
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0
go_gc_duration_seconds{quantile="0.5"} 0
go_gc_duration_seconds{quantile="0.75"} 0
go_gc_duration_seconds{quantile="1"} 0
go_gc_duration_seconds_sum 0
go_gc_duration_seconds_count 0
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 6
# HELP go_info Information about the Go environment.
# TYPE go_info gauge
go_info{version="go1.11.2"} 1
(略)
Prometheusの設定ファイルとNode_Exporterの登録
PrometheusがExporterからメトリックを取得して、時系列データベースにデータを蓄えるためにはPrometheusにExporterを収集対象として登録する必要があります。
そのため、Prometheusの設定ファイルに先程起動したNode_Exporterの設定を追加します。
その前に、Prometheusのインストール時はサンプルのものをコピーするだけであった設定ファイルであるprometheus.ymlの中身を見ておきましょう。拡張子が示すとおりにYAML形式で設定が記載されています。
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# 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'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
Exporterからメトリックを取得する部分にのみ着目すると、以下の設定が施されています。
globalのscrape_intervalでExporterから15秒周期でメトリックを取得
scrape_configsに'prometheus'としてPrometheus自分自身のメトリックを取得するjobを定義
PrometheusでExporterからメトリックを取得する際にはExporter(サービス)毎などのまとまりでjobを作って、それぞれのjobに対して取得対象などを定義していきます。
それでは、設定ファイルにNode_Exporterの設定を追加していきましょう。/etc/prometheus/prometheus.ymlのscrape_configsの末尾に以下を追記します。
scrape_configs:
(略)
- job_name: 'node'
file_sd_configs:
- files:
- /etc/prometheus/nodes.yml
メトリック取得対象の定義にはサービスディスカバリ機能を用います。今回はfile_sd_config を使用します。file_sd_configでは別なYAMLファイルに収集対象のリストを書き下す形式です。
なお、サンプルに記載されていた'prometheus' jobではstatic_config が使用されていて、これはprometheus.ymlに収集対象を直書きする形式です。サービスディスカバリはstatic_configやfile_sd_config以外にも Kubernetes 、Amazon EC2 、Microsoft Azure と連携したサービスディスカバリや、DNSのSRVレコードを使用したもの など複数存在しています。
file_sd_configに定義した/etc/prometheus/nodes.ymlへ先程起動したNode_Exporterを登録します。基本的にはtargetsに<対象ホスト>:9100と並べ立てていくのみです。また、labelsを使用することで、メトリックに任意のラベルを付加できます。今回はroleという名前のラベルを定義し、値にprometheusを入れています。ラベルは後述のPromQLでキーとして使用できるため、複数台のホストがある時「このロールのマシンだけでデータを集計したい」ということがあるケースで効力を発揮します。
- targets:
- localhost:9100
labels:
role: prometheus
設定を追加したら、promtoolのシンタックスチェック機能を使用して設定ファイルをチェックしましょう。
$ promtool check config /etc/prometheus/prometheus.yml
Checking /etc/prometheus/prometheus.yml
SUCCESS: 0 rule files found
問題がなければPrometheusをreloadして、ブラウザでPrometheusのダッシュボードの/targetsにアクセスしてみましょう。画面に'node'という項目とlocalhost:9100が存在しているようであればNode_Exporterの登録に成功しています(図4 ) 。
図4 Node_Exporter登録後のPrometuehsのダッシュボードのtarget画面
PromQLを使用したグラフの描画
Prometheusでは時系列データベースに対してPromQL という独自のクエリ言語を使用してグラフの描画やデータの加工、アラートの生成などの全般的なデータ操作を行います。このためPrometheusを使用する上でPromQLの使用は必須となります。
PromQLの簡単な例をいくつか紹介します。
PromQLの発行クライアントとして、Prometheusのダッシュボードが使えますのでブラウザでアクセスします。
一番上のテキストボックスに以下を入力してエンターキーを押下すると、先程追加したNode_Exporterで取得したload1というロードアベレージの一分間の平均値を取得したメトリックの時系列グラフを取得できます(図5 ) 。
node_load1{instance="localhost:9100"}
図5 load1のグラフ
また、テキストボックスに以下を入力してエンターキーを押下すると、Node_Exporterから収集した各コア、各モード(idle以外)のCPU使用率の時系列グラフを取得できます(図6 、注5 ) 。
irate(node_cpu_seconds_total{instance="localhost:9100", mode!="idle"}[1m]) * 100
図6 CPU使用率のグラフ
上記のクエリでは、node_cpu_seconds_totalという各コア、各モードのCPU使用時間の累計を記録したメトリックのlocalhostで、かつ直近1分間のデータのうちmodeがidle以外なものを指定しています(注6 、注7 ) 。そして、irate()という一秒あたりの率を計算する関数へ渡し、結果をパーセントの形にするために100倍しています。
Grafanaのインストールとダッシュボードの作成
先に紹介したPrometheusのダッシュボードはグラフを可視化するものですが、これはあくまで一時的なものであり、画面を閉じると消えてしまいます。また、複数のメトリックを一つのグラフに描画するということも(少なくとも容易には)できません[8] 。
Prometheusの可視化ツールとしてのデファクトスタンダードはGrafana です。PrometheusのダッシュボードとGrafanaでは基本的には以下の使い分けをします。
何か確認したいことや、異常があった時の調査では、PrometheusダッシュボードからPromQLをクエリして確認する
日常的によく見るものに関してはGrafanaダッシュボードにグラフを作成しておく
Grafanaは公式のインストールドキュメント に従ってインストールし、Grafanaを起動します。
$ sudo /bin/bash -c "echo deb https://packages.grafana.com/oss/deb stable main > /etc/apt/sources.list.d/grafana.list"
$ curl https://packages.grafana.com/gpg.key | sudo apt-key add -
$ sudo apt update
$ sudo apt install grafana
$ sudo systemctl start grafana-server.service
Grafanaの起動後、ブラウザでGrafanaをインストールしたホストの3000番ポートへアクセスすると、ログイン画面が表示されるのでadminユーザでログインします。デフォルトパスワードはadminで、入力後即座に本パスワードの設定を促されます。
ログイン後データソースとしてPrometheusを追加します。「 Add Data Source」をクリックし、Prometheusを選択します(図7 、図8 ) 。
図7 初回ログイン時のダッシュボード
図8 データソースの追加画面。絞り込みでPrometheusのみが表示されるようにしている
Prometheusの設定画面に入りますので、「 URL」へPrometheusのURLを入力し、「 Save & Test」をクリックします(図9 ) 。テストが成功すればPrometheusの登録は完了です。
図9 Prometheusの設定画面。URLにPrometheusのURLを入力すれば良い
データソースを追加すれば後はダッシュボードにPromQLを入力して任意のグラフなどを表示できます(図10 ) 。
図10 Node_Exporterの一部のメトリックをグラフ表示するダッシュボード。いずれもPromQLを実行した結果を出力している
また、GrafanaはGrafana Labにアップロードされているダッシュボード をダウンロードして使用することもできます。